MongoDB查询从嵌套数组中筛选子文档

MongoDB查询从嵌套数组中筛选子文档,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,鉴于这种嵌入式文档结构: organisation district property installation installation_type 我只希望检索安装类型=例如“燃气锅炉”的属性 我试过: db.organisation.find({ "district.property.installation.installation_type": { $all: ['Gas boiler'] }}) 但这会返回任何带有燃气锅炉的组织的整个文档。

鉴于这种嵌入式文档结构:

organisation
  district
    property
      installation 
        installation_type
我只希望检索安装类型=例如“燃气锅炉”的属性

我试过:

db.organisation.find({ "district.property.installation.installation_type": { $all: ['Gas boiler'] }})
但这会返回任何带有燃气锅炉的组织的整个文档。这意味着我也得到了没有燃气锅炉的房产。我想要一个只有“燃气锅炉”的属性列表

示例文档:

db.organisation.insert({
  _id: 'Organsiation 1',
  district: [
  {
    _id: 'District 1',
    property: [
      {
        _id: 'Property 1',
        address_line_1: 'Adress 1',
        installation: [
          {
            _id: 'HS01',
            installation_type: 'Gas boiler',
            component: [
              {
                _id: 'P01',
                component_type: 'Circulation pump',
              },
              {
                _id: 'EXP01',
                component_type: 'Expansion tank',
              },
            ],
          },
          {
            _id: 'HW01',
            installation_type: 'Electric water heater',
            component: [
              {
                _id: 'P01',
                component_type: 'Circulation pump',
              },
            ],
          },
          {
            _id: 'V01',
            installation_type: 'Ventilation',
          }
        ]
      },
    ]
  },
  {
    _id: 'District 2',
    property: [
      {
        _id: 'Property 2',
        address_line_1: 'Adress 2',
        installation: [
          {
            _id: 'HS01',
            installation_type: 'Geo Heat Pump',
          },
          {
            _id: 'HS02',
            installation_type: 'Gas boiler',
          }
        ]
      },
      {
        _id: 'Property 3',
        installation: [
          {
            _id: 'HS01',
            installation_type: 'Gas boiler',
          } 
        ]
      },
    ],
  }
]
})

如何执行此操作?

使用此多个嵌套数组,您可以执行
$unwind
或使用如下筛选器,但使用
$unwind
将使用大量文档来分解集合,因此这样做应该是可行的,因为它应该在小于原始集合大小的文档上运行
$addFields

db.collection.aggregate([
    /** This match can be optional if dealing with data set of small size, else it can help a lot to filter docs which has at-least 'Gas boiler' */
    {
      $match: {
        "district.property.installation.installation_type": "Gas boiler"
      }
    },
    /** Iterate over each array till property array but on installation use filter to filter only object matches with required criteria,
     *  Use mergeObjects to merge actual object with returned array, to preserve other fields apart from `property` & `installation` */
    {
      $addFields: {
        district: {
          $map: {
            input: "$district",
            as: "d",
            in: {
              $mergeObjects: [
                "$$d",
                {
                  property: {
                    $map: {
                      input: "$$d.property",
                      as: "p",
                      in: {
                        $mergeObjects: [
                          "$$p",
                          {
                            installation: {
                              $filter: {
                                input: "$$p.installation",
                                cond: {
                                  $eq: [
                                    "$$this.installation_type",
                                    "Gas boiler"
                                  ]
                                }
                              }
                            }
                          }
                        ]
                      }
                    }
                  }
                }
              ]
            }
          }
        }
      }
    }
  ])

测试:

您能给我们提供样品文件吗!!完成请看问题Thankyou@whoami-非常感谢您在这方面花费的时间。我将阅读并消化:)