在Double Nested Array MongoDB中查找

时间:2015-03-16 07:39:33

标签: mongodb mongodb-query aggregation-framework

我在mongodb中有这个收藏

{
"_id" : "777",
"someKey" : "someValue",
"someArray" : [
    {
        "name" : "name1",
        "someNestedArray" : [
            {
                "name" : "value"
            },
            {
                "name" : "delete me"
            }
        ]
    }
  ]
}

我想根据someArray.someNestedArray.name查找文档 但我找不到任何有用的链接所有关于更新嵌套数组的搜索结果 我正在尝试这个,但什么都不返回

db.mycollection.find({"someArray.$.someNestedArray":{"$elemMatch":{"name":"1"}}})
db.mycollection.find({"someArray.$.someNestedArray.$.name":"1"})

和其他一些东西

如何通过双嵌套数组mongodb中的元素找到?

2 个答案:

答案 0 :(得分:40)

从最简单的意义上说,这只是遵循MongoDB使用的"dot notation"的基本形式。无论内部数组成员所在的数组成员是什么,只要它匹配一个值:

,这将起作用
db.mycollection.find({
    "someArray.someNestedArray.name": "value"
})

对于单个字段"这是好的。值,用于匹配您将使用$elemMatch的多个字段:

db.mycollection.find({
    "someArray": { 
        "$elemMatch": {
            "name": "name1",
            "someNestedArray": {
                "$elemMatch": {
                    "name": "value",
                    "otherField": 1
                }
            }
        }
    }
})

匹配包含某个字段的文档,该字段位于"路径"匹配值。如果您打算“匹配并过滤”#34;结果只返回匹配的元素,这对位置运算符投影as quoted是不可能的:

  

嵌套数组

     

位置$运算符不能用于遍历多个数组的查询,例如遍历嵌套在其他数组中的数组的查询,因为$ placeholder的替换是单个值

现代MongoDB

我们可以在此处应用$filter$map来完成此操作。真的需要$map,因为"内部"数组可以通过"过滤"和"外部"来改变。数组当然不符合"内部"被剥夺了所有元素。

再次遵循在每个数组中实际具有多个属性匹配的示例:

db.mycollection.aggregate([
  { "$match": {
    "someArray": {
      "$elemMatch": {
         "name": "name1",
         "someNestedArray": {
           "$elemMatch": {
             "name": "value",
             "otherField": 1
           }
         }
       }
    }
  }},
  { "$addFields": {
    "someArray": {
      "$filter": {
        "input": {
          "$map": {
            "input": "$someArray",
            "as": "sa",
            "in": {
              "name": "$$sa.name",
              "someNestedArray": {
                "$filter": {
                  "input": "$$sa.someNestedArray",
                  "as": "sn",
                  "cond": {
                    "$and": [
                      { "$eq": [ "$$sn.name", "value" ] },
                      { "$eq": [ "$$sn.otherField", 1 ] }
                    ]
                  }
                }
              }             
            }
          },
        },
        "as": "sa",
        "cond": {
          "$and": [
            { "$eq": [ "$$sa.name", "name1" ] },
            { "$gt": [ { "$size": "$$sa.someNestedArray" }, 0 ] }
          ]
        }
      }
    }
  }}
])

因此在"外部"数组$filter实际上是查看"内部"的$size数组经过"过滤后#34;本身,所以你可以在整个内部数组确实匹配注意时拒绝这些结果。

较旧的MongoDB

为了"项目"只有匹配的元素,您需要.aggregate()方法:

db.mycollection.aggregate([
    // Match possible documents
    { "$match": {
        "someArray.someNestedArray.name": "value"
    }},

    // Unwind each array
    { "$unwind": "$someArray" },
    { "$unwind": "$someArray.someNestedArray" },

    // Filter just the matching elements
    { "$match": {
        "someArray.someNestedArray.name": "value"
    }},

    // Group to inner array
    { "$group": {
        "_id": { 
            "_id": "$_id", 
            "name": "$someArray.name"
        },
        "someKey": { "$first": "$someKey" },
        "someNestedArray": { "$push": "$someArray.someNestedArray" }
    }},

    // Group to outer array
    { "$group": {
        "_id": "$_id._id",
        "someKey": { "$first": "$someKey" },
        "someArray": { "$push": {
            "name": "$_id.name",
            "someNestedArray": "$someNestedArray"
        }}
    }} 
])

这允许你过滤"嵌套数组中的匹配项,用于文档中的一个或多个结果。

答案 1 :(得分:0)

您还可以尝试以下操作:

db.collection.aggregate(
    { $unwind: '$someArray' },
    {
        $project: {
            'filteredValue': {
                $filter: {
                  input: "$someArray.someNestedArray",
                  as: "someObj",
                  cond: { $eq: [ '$$someObj.name', 'delete me' ] }
                }
            }
        }
    }
)