Node.js Mongo$使用mongoose查找嵌套数组3层

Node.js Mongo$使用mongoose查找嵌套数组3层,node.js,mongodb,mongoose,Node.js,Mongodb,Mongoose,我有这样的内部外部服务型号: name: String, salary: Number, services: [ { category: { ref: 'ServiceCategories', type: Schema.Types.ObjectId }, types: [ { ref: 'ServiceType', type: S

我有这样的内部
外部服务
型号:

name: String,
salary: Number,
services: [
      {
        category: {
          ref: 'ServiceCategories',
          type: Schema.Types.ObjectId
        },
        types: [
          {
            ref: 'ServiceType',
            type: Schema.Types.ObjectId
          }
        ]
      }
    ]
我有一个内置的
事件
模型:

  outsideServices: {
      ref: 'OutsideService',
      type: Schema.Types.ObjectId
    }
因此,当从api请求
事件时,响应如下:

[
  {
    category: '5cf655135a1b72106777c238',
    types: ['5cf655a85a1b72106777c239']
  },
  {
    category: '5cf656525a1b72106777c23b',
    types: ['5cf656835a1b72106777c23c']
  }
];
如何能够同时查找
类别
类型
ref并在我的回复中保留上述结构

以下是我到目前为止所做的尝试,但无法获得预期的结果:

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

所以您使用的是mongoose模式,但随后将转到MongoDB进行聚合

您需要使用,它来自
mongoose


填充是将
refs
与您等联系起来的内容。

您可以在下面的聚合中尝试。使用$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"
}

感谢您的回复,我需要使用聚合,因为我在到达此阶段之前会进行更多查询,
aggregate.lookup({})
正在使用mongoose,我不太明白您为什么要指出我使用mongoose,然后转到mongoDB。如果我想保留整个文档,而不仅仅是
{{u-id:null,services:[…]
在响应中我必须做什么?我尝试了
{$group:{{{u-id:null,services:{$push:'$services'},doc:{$first:'$$ROOT'},{$replacetroot:{newRoot:'$doc'}}
但这将导致只返回一个服务(因为
$first
),不客气。插入
{$addFields:{“doc.services”:“$services”}}
在您的组和replaceRoot阶段之间。这就是您要问的吗?我已经更新了这个问题,
服务
模式有更多的属性,不仅仅是服务。我想在聚合后保留它们。我可以
$group
使用
$first
和下一阶段
$project
的所有内容,但我有fiv更多的
refs
我需要使用相同的代码进行查找和分组,这需要太多的代码,它们都是大型对象,我希望能有一种更简单的方法。对不起,我没有听清楚。addFields stage在阶段中更改/创建字段的同时保留现有字段。要查找,您必须一次执行一个,没有快捷方式。看看你能否用更多的细节更新问题,我可以试试。