Mongo $ lookup使用mongoose嵌套3级数组

时间:2019-06-14 13:28:04

标签: node.js mongodb mongoose

我在outsideServices模型中拥有此功能:

name: String,
salary: Number,
services: [
      {
        category: {
          ref: 'ServiceCategories',
          type: Schema.Types.ObjectId
        },
        types: [
          {
            ref: 'ServiceType',
            type: Schema.Types.ObjectId
          }
        ]
      }
    ]

我在incidents模型中拥有此功能:

  outsideServices: {
      ref: 'OutsideService',
      type: Schema.Types.ObjectId
    }

因此,当从api请求incidents时,响应如下:

[
  {
    category: '5cf655135a1b72106777c238',
    types: ['5cf655a85a1b72106777c239']
  },
  {
    category: '5cf656525a1b72106777c23b',
    types: ['5cf656835a1b72106777c23c']
  }
];

如何查找categoriestypes引用并在响应中保留上面的结构?

这是到目前为止我尝试过的方法,但无法获得预期的结果:

aggregate.lookup({
      from: 'outsideservices',
      let: { serviceId: '$outsideServices' },
      pipeline: [
        { $match: { $expr: { $eq: ['$_id', '$$serviceId'] } } },
        {
          $lookup: {
            from: 'servicecategories',
            let: { services: '$services.category' },
            pipeline: [{ $match: { $expr: { $in: ['$_id', '$$services'] } } }],
            as: 'category'
          }
        },
        {
          $lookup: {
            from: 'servicetypes',
            let: { services: '$services.types' },
            pipeline: [
              { $match: { $expr: { $in: ['$_id', '$$services'] } } }
            ],
            as: 'types'
          }
        }
      ],
      as: 'outsideService'
    });

想要的结果/结果与上面的响应类似,但是填充的文档而不是ObjectId s

MongoDB版本4.0.10

2 个答案:

答案 0 :(得分:1)

因此,您使用的是mongoose模式,但随后转到mongoDB进行聚合。

您需要使用populate,它是mongoose中的match stage

填充将为您绑定refs等。

答案 1 :(得分:1)

您可以尝试以下汇总。使用$ unwind解构数组,然后使用$ lookup提取类别和类型,最后使用$ group返回原始结构。

{
  "from":"outsideservices",
  "let":{"serviceId":"$outsideServices"},
  "pipeline":[
    {"$match":{"$expr":{"$eq":["$_id","$$serviceId"]}}},
    {"$unwind":"$services"},
    {"$lookup":{
    "from":"servicecategories",
    "localField":"services.category",
    "foreignField":"_id",
    "as":"services.category"
    }},
    {"$lookup":{
    "from":"servicetypes",
    "localField":"services.types",
    "foreignField":"_id",
    "as":"services.types"
    }},
    {"$group":{
    "_id":null,
    "services":{"$push":"$services"}
    }}
  ],
  "as":"outsideService"
}