MongoDB nested array query

前端 未结 3 1242
抹茶落季
抹茶落季 2020-12-01 01:08

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

相关标签:
3条回答
  • 2020-12-01 01:49

    Use nested elemMatch to search nested levels within arrays.

    Details Querying an array of arrays in MongoDB

    0 讨论(0)
  • 2020-12-01 01:49

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

    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.

    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.

    $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)

    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.)

    Hope it helps

    0 讨论(0)
  • 2020-12-01 02:09

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

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

    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:

    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:

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

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

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

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

    0 讨论(0)
提交回复
热议问题