如何通过在mongo中过滤嵌套数组的嵌套数组来查询对象的嵌套数组

时间:2019-07-23 21:27:55

标签: mongodb mongodb-query aggregation-framework

我有一个mongodb(v.3.4)组件对象集合,其中包含子组件列表,而子组件包含零件列表。

{
    "_id": "1_1",
    "name": "Component 1",
    "subComponents": [
        {
            "_id": "subId_1",
            "name": "subComponentName_subId_1",
            "type": "SUB_COMPONENT_TYPE_1",
            "parts": [
                {
                    "_id": "partId_1",
                    "type": "type_partId_1",
                    "description": "part description partId_1",
                    "status": true
                },
                {
                    "_id": "partId_2",
                    "type": "type_partId_2",
                    "description": "part description partId_2",
                    "status": true
                },
                {
                    "_id": "partId_3",
                    "type": "type_partId_3",
                    "description": "part description partId_3",
                    "status": true
                }
            ]
        },
        {
            "_id": "subId_2",
            "name": "subComponentName_subId_2",
            "type": "SUB_COMPONENT_TYPE_2",
            "parts": [
                {
                    "_id": "partId_1",
                    "type": "type_partId_1",
                    "description": "part description partId_1",
                    "status": true
                },
                {
                    "_id": "partId_2",
                    "type": "type_partId_2",
                    "description": "part description partId_2",
                    "status": true
                },
                {
                    "_id": "partId_3",
                    "type": "type_partId_3",
                    "description": "part description partId_3",
                    "status": true
                }
            ]
        },
        {
            "_id": "subId_3",
            "name": "subComponentName_subId_3",
            "type": "SUB_COMPONENT_TYPE_3",
            "parts": [
                {
                    "_id": "partId_1",
                    "type": "type_partId_1",
                    "description": "part description partId_1",
                    "status": true
                },
                {
                    "_id": "partId_2",
                    "type": "type_partId_2",
                    "description": "part description partId_2",
                    "status": true
                },
                {
                    "_id": "partId_3",
                    "type": "type_partId_3",
                    "description": "part description partId_3",
                    "status": true
                }
            ]
        }
    ],
    "_class": "com.ak.mongodb.domain.Component"
}

我想查询组件的子组件(例如,按componentId和subComponentId),并同时按类型过滤SubCompoent的某些部分。

到目前为止,我可以按componentId和subComponentId进行过滤,但是我得到了一个Component对象!

这是我的汇总:

db.components.aggregate([
    { $match: {
        _id: "1_1"
    }}, 
    { $project: {
        _id: 1,
        name: 1,
        subComponents: {
        $filter: { 
            input: "$subComponents", 
            as: "subComponent", 
            cond: { $eq: ["$$subComponent._id", "subId_1"]}
            }
        }
    }}
])

我得到的结果:

{
    "_id" : "1_1",
    "name" : "Component 1",
    "subComponents" : [
        {
            "_id" : "subId_1",
            "name" : "subComponentName_subId_1",
            "type" : "SUB_COMPONENT_TYPE_1",
            "parts" : [
                {
                    "_id" : "partId_1",
                    "type" : "type_partId_1",
                    "description" : "part description partId_1",
                    "status" : true
                },
                {
                    "_id" : "partId_2",
                    "type" : "type_partId_2",
                    "description" : "part description partId_2",
                    "status" : true
                },
                {
                    "_id" : "partId_3",
                    "type" : "type_partId_3",
                    "description" : "part description partId_3",
                    "status" : true
                }
            ]
        }
    ]
}

我要实现的是一个只有部分类型为“ type_partId_1”和“ type_partId_2”的子组件:

{
            "_id" : "subId_1",
            "name" : "subComponentName_subId_1",
            "type" : "SUB_COMPONENT_TYPE_1",
            "parts" : [
                {
                    "_id" : "partId_1",
                    "type" : "type_partId_1",
                    "description" : "part description partId_1",
                    "status" : true
                },
                {
                    "_id" : "partId_2",
                    "type" : "type_partId_2",
                    "description" : "part description partId_2",
                    "status" : true
                }
            ]
        }

1 个答案:

答案 0 :(得分:1)

要实现此目的,您需要添加几个阶段:首先, $unwind subComponent数组,并将subComponenet定义为文档的新根目录与 $replaceRoot 。然后,使用第二个 $project 阶段来过滤parts数组:

db.collection.aggregate([
  { "$match": { "_id": "1_1" }},
  { "$project": {
    "subComponents": {
      "$filter": {
        "input": "$subComponents",
        "as": "subComponent",
        "cond": { "$eq": ["$$subComponent._id", "subId_1"] }
      }
    }
  }},
  { "$unwind": "$subComponents" },
  { "$replaceRoot": { "newRoot": "$subComponents" }},
  { "$project": {
    "name": 1,
    "type": 1,
    "parts": {
      "$filter": {
        "input": "$parts",
        "as": "part",
        "cond": { "$in": ["$$part._id", ["partId_1", "partId_2"]] }
      }
    }
  }}
])

输出:

[
  {
    "_id": "subId_1",
    "name": "subComponentName_subId_1",
    "type": "SUB_COMPONENT_TYPE_1",
    "parts": [
      {
        "_id": "partId_1",
        "description": "part description partId_1",
        "status": true,
        "type": "type_partId_1"
      },
      {
        "_id": "partId_2",
        "description": "part description partId_2",
        "status": true,
        "type": "type_partId_2"
      }
    ]
  }
]

您可以在线尝试:mongoplayground.net/p/GhWTHnud-vm