MongoDB 嵌套数组查询

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17303833/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 13:18:05  来源:igfitidea点击:

MongoDB nested array query

mongodbmongodb-querynosql

提问by dgorur

I've asked this as a comment on anotherquestion, and also posted a questionon mongodb-user. No responses so far, so I'm resorting to asking a separate question.

我已经问过这个作为对另一个问题的评论,并且还在mongodb-user 上发布了一个问题。到目前为止没有回应,所以我求助于提出一个单独的问题。

The documentationstates:

文件指出:

If the field holds an array, then the $in operator selects the documents whose field holds an array that contains at least one element that matches a value in the specified array (e.g. , , etc.)

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

I'm using:

我正在使用:

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

In MongoDB shell:

在 MongoDB 外壳中:

db.nested.insert({'level1': {'level2': [['item00', 'item01'], ['item10', 'item11']]}})

Here's a list of queries that should work according to the documentation, and the results they produce:

以下是应根据文档工作的查询列表及其产生的结果:

Why doesn't this work?

为什么这不起作用?

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

Why do I need the $all?

为什么我需要 $all?

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

At least one of the following should work, right?

以下至少一项应该有效,对吗?

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

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

Any ideas? We're considering abandoning MongoDB if the query syntax doesn't work as advertised.

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

Thanks!

谢谢!

采纳答案by dgorur

Use nested elemMatchto search nested levels within arrays.

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

Details Querying an array of arrays in MongoDB

详情查询 MongoDB 中的数组数组

回答by AntonioOtero

After running some queries, I came to the conclusion that $in doesn't work for an array of arrays.

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

You can use $elemMatchinstead and it'll work, but it is frustrating that MongoDB's documentation doesn't warn about it.

你可以改用$elemMatch它,它会起作用,但令人沮丧的是 MongoDB 的文档没有警告它。

I created this document:

我创建了这个文件:

{
      "_id": "51cb12857124a215940cf2d4",
      "level1": [
        [
          "item00",
          "item01"
        ],
        [
          "item10",
          "item11"
        ]
      ],
      "items": [
        "item20",
        "item21"
      ]
}

Notice that the field "items" is an array of strings and this query works perfectly:

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

db.nested.findOne({"items":{"$in":["item20"]} })

Now, "level1.0" is also an array of strings, the only difference is that it's inside another array. This query should work but isn't:

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

db.nested.findOne({"level1.0":{"$in":["item00"]} })

The only way to get the result is using $elemMatch:

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

db.nested.findOne({"level1":{"$elemMatch":{"$in":['item00']}} })

So $elemMatchsolves the problem, but the real solution is to update MongoDB's documentation to states that $indoesn't work for arrays of arrays. Perhaps you should submit a request to 10gen.

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

回答by AntonioOtero

Short answer: $in is for a single-value field and $all is for arrays.

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

First, db.nested.findOne({'level1.level2.0': 'item00'})doesn't work because level1.level2.0 holds an array and you are trying to compare it with a single value.

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

Now, db.nested.findOne({'level1.level2.0': {'$in': ['item00']}})doesn't work either because of a similar reason. $in is for comparing a field with a single value (you have an array) with several values in an array (specified in the query). $in is saying: give me the docs that have this field which value is included in this array.

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

$all is working because it is saying: give me the docs that have this field with several values and all the values of this array (in the query) are included in that field. (edited)

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

Might be hard to get but look at what the documentation says for each:

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

$all selects the documents where the field holds an array and contains all elements(e.g. <value>, <value1>, etc.) in the array.

$in selects the documents where the field value equals any value in the specified array(e.g. <value1>, <value2>, etc.)

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

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

Hope it helps

希望能帮助到你