MongoDB嵌套数组查询

dgo*_*rur 40 mongodb nosql mongodb-query

我已将此问作为对另一个问题的评论,并在mongodb-user上发布了一个问题.到目前为止没有回复,所以我要求另外提问.

文件规定:

如果该字段包含数组,则$ in运算符选择其字段包含一个数组的文档,该数组包含至少一个与指定数组中的值匹配的元素(例如,等等)

我正在使用:

mongod --version:
db version v2.2.2, pdfile version 4.5
Thu May 30 12:19:12 git version: d1b43b61a5308c4ad0679d34b262c5af9d664267

mongo --version:
MongoDB shell version: 2.0.4
Run Code Online (Sandbox Code Playgroud)

在MongoDB shell中:

db.nested.insert({'level1': {'level2': [['item00', 'item01'], ['item10', 'item11']]}})
Run Code Online (Sandbox Code Playgroud)

这是根据文档应该工作的查询列表,以及它们产生的结果:

为什么这不起作用?

> db.nested.findOne({'level1.level2.0': 'item00'})
null
Run Code Online (Sandbox Code Playgroud)

为什么我需要$ all?

> db.nested.findOne({'level1.level2.0': {'$all': ['item00']}})
{
    "_id" : ObjectId("51a7a4c0909dfd8872f52ed7"),
    "level1" : {
        "level2" : [
            [
                "item00",
                "item01"
            ],
            [
                "item10",
                "item11"
            ]
        ]
    }
}
Run Code Online (Sandbox Code Playgroud)

至少有下列之一应该可以工作,对吧?

> db.nested.findOne({'level1.level2.0': {'$in': ['item00']}})
null

> db.nested.findOne({'level1.level2': {'$in': ['item00']}})
null
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?如果查询语法不像宣传的那样工作,我们正在考虑放弃MongoDB.

谢谢!

Ant*_*ero 41

运行一些查询后,我得出的结论是$ in不适用于数组数组.

您可以使用$elemMatch它而且它可以工作,但令人沮丧的是MongoDB的文档没有对此发出警告.

我创建了这个文档:

{
      "_id": "51cb12857124a215940cf2d4",
      "level1": [
        [
          "item00",
          "item01"
        ],
        [
          "item10",
          "item11"
        ]
      ],
      "items": [
        "item20",
        "item21"
      ]
}
Run Code Online (Sandbox Code Playgroud)

请注意,字段"items"是一个字符串数组,此查询完美运行:

db.nested.findOne({"items":{"$in":["item20"]} })
Run Code Online (Sandbox Code Playgroud)

现在,"level1.0"也是一个字符串数组,唯一的区别是它在另一个数组中.此查询应该有效,但不是:

db.nested.findOne({"level1.0":{"$in":["item00"]} })
Run Code Online (Sandbox Code Playgroud)

获得结果的唯一方法是使用$ elemMatch:

db.nested.findOne({"level1":{"$elemMatch":{"$in":['item00']}} })
Run Code Online (Sandbox Code Playgroud)

因此$elemMatch解决了这个问题,但真正的解决方案是将MongoDB的文档更新为$in不适用于数组数组的状态.也许您应该向10gen提交申请.


dgo*_*rur 8

使用嵌套elemMatch来搜索数组中的嵌套级别.

详细信息查询MongoDB中的数组数组


Ant*_*ero 5

简短的答案:$ in用于单值字段,$ all用于数组。

首先,db.nested.findOne({'level1.level2.0': 'item00'})它不起作用,因为level1.level2.0拥有一个数组,并且您试图将其与单个值进行比较。

现在,db.nested.findOne({'level1.level2.0': {'$in': ['item00']}})由于类似的原因也不起作用。$ in用于比较具有单个值(您有一个数组)和具有数组中多个值(在查询中指定)的字段。$ in的意思是:给我包含该字段的文档,该值包含在此数组中。

$ all正在工作,因为它是在说:给我包含具有多个值的此字段的文档,并且此数组(在查询中)的所有值都包含在该字段中。(编辑)

可能很难获取,但请查看文档中对每个内容的说明:

$ all选择该字段 所在的文档,该文档包含数组并包含数组中的所有元素(e.g. <value>, <value1>, etc.

$ in选择文档,其中字段值等于指定数组e.g. <value1>, <value2>, etc.中的任何值

希望能帮助到你