我在mongodb有这个系列

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

我想查找基于someArray的文档.某个地方.名称

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

还有别的

如何在双嵌套数组mongodb中按元素查找?

推荐答案

在最简单的意义上,这只是遵循MongoDB使用的基本形式"dot notation".无论内部数组成员位于哪个数组成员中,只要它与一个值匹配,这都将起作用:

db.mycollection.find({
    "someArray.someNestedArray.name": "value"
})

对于"单个字段"值来说,这很好,对于匹配多个字段,您可以使用$elemMatch:

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

它与文档相匹配,文档中包含的内容在该"路径"处具有与值匹配的字段.如果您打算"匹配并过滤"结果,以便只返回匹配的元素,那么使用位置运算符投影as quoted:

Nested Arrays

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

现代MongoDB

我们可以在这里应用$filter$map.$map是真正需要的,因为"内部"数组可能会因"过滤"而改变,"外部"数组当然不符合"内部"go 掉所有元素时的条件.

再次以每个数组中实际有多个要匹配的属性为例:

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,因此当整个内部数组实际上不匹配时,可以拒绝这些结果.

老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"
        }}
    }} 
])

这允许您在嵌套数组中"筛选"匹配项,以在文档中查找一个或多个结果.

Mongodb相关问答推荐

如何让mongoDB根据用户集合中提供的_id为发送者和接收者填充事务集合的子字段

获取响应周期中的特定键和值

如何在 kubernetes 中获取分片 mongodb 的备份

MongoDB 聚合 - 条件 $lookup 取决于字段是否存在

使用新字段插入数据或使用 updateOne mongodb 有条件地更新

mongodb中集合的最大大小是多少

Meteor 如何接收对 MongoDB 查询结果的更新?

Mongo 重启错误 -- /var/run/mongodb/mongod.pid 存在

MongoDB插入引发重复键错误

用 BsonRepresentation(BsonType.ObjectId) vs BsonId vs ObjectId 在 C# 中装饰属性之间的区别

在 Ubuntu 14.04 中安装 MongoDB 失败

Mongoose 连接认证失败

MongoDB 日志(log)文件和 oplog 有何不同?

插入违反唯一索引的 MongoDB 文档时如何捕获错误?

查询不等于 null 或空的地方

mongoose:按字母顺序排序

在mongoose中查询虚拟属性

用 MongoDB 中的属性表示多对多关系的最佳模型

MongoDB Compass:select distinct field values

如何从集合中删除除 MongoDB 中的文档之外的所有文档