有条件地填充Mongo查询中的路径

时间:2017-12-14 01:47:11

标签: mongodb mongoose mongoose-populate

我有以下架构:

const connectionSchema = new Schema( {
  ...
  event: {
    type: Schema.ObjectId,
    ref: 'events'
  },
  place: {
    type: Schema.ObjectId,
    ref: 'places'
  },
} )

const eventsSchema = new Schema( {
  ...
  place: {
    type: Schema.ObjectId,
    ref: 'places'
  },
} )

当我查询单个connectionconnection的集合时,我希望它检查是否指定了event,如果是,则返回place event,否则从place返回connection

当我查询单个连接时,我正在做这样的事情:

let c
const execFunction = ( err, connection ) => {
  if ( connection.event ) {
    connection.place = connection.event.place
  }
  c = connection
}

const connectionPromise = Connection.findById( connectionId )
connectionPromise.populate( { path: 'event', populate: { path: 'place' } } )
connectionPromise.populate( 'place' )
connectionPromise.exec( execFunction )

但是,我试图避免在execFunction中遍历整个集合,以便在我查询集合时对每个单独的结果执行替换逻辑。

是否有更好的(即更高效的)方法来解决这个问题?

1 个答案:

答案 0 :(得分:0)

据我所知,没有办法用猫鼬做有条件的人群。

在你的情况下,我认为你正试图做“深度人口”。

开箱即用不支持深度人口,但有一个插件! mongoose-deep-populate

const connectionQuery = Connection.findById( connectionId )
connectionQuery.populate( 'place event event.place' )
connectionQuery.exec( execFunction );

我猜测'place event.place'可能会这样做:'event'应该暗示。

我还希望,如果未定义placeeventevent.place,则不会出现错误,也不会填充错误。

但我不认为在place可用时,在一行中有任何方法可以跳过填充event.place

顺便说一下,如果你想使用promises,你可以像这样写:

return Connection.findById( connectionId )
    .populate( 'place event event.place' )
    .then( onSuccessFunc );

传播错误,或:

Connection.findById( connectionId )
    .populate( 'place event event.place' )
    .then( onSuccessFunc )
    .catch( onErrorFunc );

在本地处理错误。我发现这比回调更可取,因为我们不必在每个阶段都担心if (err)