【问题标题】:Mongodb Aggregate Complex Document with Nested LookupsMongodb 使用嵌套查找聚合复杂文档
【发布时间】:2020-08-19 01:21:03
【问题描述】:

我有这些收藏:

网站

{
  _id: ObjectId("5acdb8f65ea63a27c1facf86"),
  TemplateId: ObjectId("sdfsdfs34234234sdf"),
}

模板

{
  _id: ObjectId("sdfsdfs34234234sdf"),
  Type: "Site",
  Name: "Site 1",
  Sections:[{
     id: ObjectId("8asdf89asd8f9sdf"),
     Header: "Header1",
     FieldItems: [
           {
            FieldId: ObjectId("jsd32423423423"),
            x: 1,
            y: 0
           },
           {
            FieldId: ObjectId("2342sdffafdasdfdfs"),
            x: 1,
            y: 1
           }
          ]
        },
       (...more sections...)
     ]
}

字段

{
  _id: ObjectId("jsd32423423423"),
  Type: "Phone",
  Name: "Phone_Test"
},
{
  _id: ObjectId("2342sdffafdasdfdfs"),
  Type: "Numeric",
  Name: "Number_Test"
}
            

我是 MongoDB 新手,但花了几天时间阅读问题和答案以及文档。我正在使用 MongoDB 4.2.6。我正在尝试返回格式如下的结果:

{
  id: ObjectId("5acdb8f65ea63a27c1facf86"),
  TemplateId: ObjectId("sdfsdfs34234234sdf"),
  Template: {
   id: ObjectId("sdfsdfs34234234sdf"),
   Type: "Site",
   Sections:[{
     id: ObjectId("8asdf89asd8f9sdf"),
     Header: "Header1",
     FieldItems: [
        {
          FieldId: ObjectId("jsd32423423423"),
          x: 1,
          y: 0,
          Field: {
              _id: ObjectId("jsd32423423423"),
              Type: "Phone",
              Name: "Phone_Test"
           }
        }, (...)]
      }]
}
  

我已经编写了一个带有嵌套查找的聚合查询,以使我大部分时间都在那里,但为了让它工作,我不得不展开 Sections 和 FieldItems。我还没有想出一种方法来让数组达到我想要的方式。我试过 group 但子数组有问题。我什至不确定这是否是获得所需结果的最佳方式:

db.getCollection("AppSites").aggregate(
[
    { 
        "$lookup" : { 
            "from" : "AppTemplates", 
            "let": {"template_id": "$TemplateId"},
            "pipeline": [
                { "$match": { "$expr": { "$eq" : ["$_id", "$$template_id"] } } },
                { "$unwind": "$Sections"},
                { "$unwind": "$Sections.FieldItems"},
                {
                    "$lookup": {
                        "from": "AppFields",
                        "let": {"field_id": "$Sections.FieldItems.FieldId"},
                        "pipeline": [
                            { "$match": { "$expr": { "$eq": ["$_id", "$$field_id"] } } }
                        ],
                        "as": "Sections.FieldItems.Field"
                    }
                }
            ],
            "as" : "Templates"
        }
    }
]
);

【问题讨论】:

    标签: mongodb


    【解决方案1】:

    你已经使用了两次$unwind,所以你需要使用两次$group。

    {
      $group: {
        _id: {
          secId: "$_id",
          fId: "$Sections.id"
        },
        Type: {
          $first: "$Type"
        },
        Name: {
          $first: "$Name"
        },
        Header: {
          $first: "$Sections.Header"
        },
        fieldItems: {
          $push: "$Sections.FieldItems"
        }
      }
    },
    {
      $group: {
        _id: "$_id.secId",
        Type: {
          $first: "$Type"
        },
        Name: {
          $first: "$Name"
        },
        Sections: {
          $push: {
            id: "$_id.fId",
            Header: "$Header",
            fieldItems: "$fieldItems"
          }
        }
      }
    }
    
    1. 第一组 - 对子对象进行分组。但是Type、Name和Header需要分别设置为父子数组。
    2. 第二组 - 对父对象进行分组。我们在对子项进行分组时获取每个独立字段。在这里,我们只需要以正确的顺序对其进行设置。

    工作Mongo playground

    注意:当你使用$lookup时,它会提供一个数组。但是有些地方你只是把它当作对象。我不知道你是否加入了一对一的关系。如果是这样,您可以使用positional operator in projection 或arrayElemAt

    【讨论】:

      猜你喜欢
      • 2020-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-26
      • 2016-07-01
      • 2014-03-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多