MongoDB: what is the difference between $elemMatch and $and to find objects inside array?

前端 未结 2 671
不思量自难忘°
不思量自难忘° 2021-01-24 01:15

Is there any logical difference between the usage of the query operator $and

db.collection.find({$and: [{\"array.field1\": \"someValue\"}, {\"array.         


        
2条回答
  •  陌清茗
    陌清茗 (楼主)
    2021-01-24 02:00

    I will explain this with an example. Consider the collection arrays. It has a field called arr which is an array of embedded documents (with fields a and b).

    Some documents in the arrays collection:

    { "_id" : 1, "arr" : [ { "a" : "a1", "b" : "b1" }, { "a" : "a2", "b" : "b2" } ] }
    { "_id" : 2, "arr" : [ { "a" : "a1", "b" : "b11" }, { "a" : "a2", "b" : "b22" } ] }
    { "_id" : 3, "arr" : [ { "a" : "a2", "b" : "b1" }, { "a" : "a", "b" : "b1" } ] }
    { "_id" : 4, "arr" : [ { "a" : "a1", "b" : "b91" }, { "a" : "a29", "b" : "b1" } ] }
    

    I want to find all documents with the array embedded-document fields a="a1" AND b="b1". Note this must be within the same element embedded-document of the array. I use $elemMatch for this and get the desired result.

    > db.arrays.find( { arr: { $elemMatch: { a: "a1", b: "b1" } } } )
    ==>
    { "_id" : 1, "arr" : [ { "a" : "a1", "b" : "b1" }, { "a" : "a2", "b" : "b2" } ] }
    

    Now, if I use the $and operator like in the following query, the results are not correct. As you can see an additional document is selected. The query worked with the array embedded-document fields a="a1" OR b="b1".

    > db.arrays.find({$and: [ { "arr.a": "a1" }, { "arr.b": "b1" } ] } )
    ==>
    { "_id" : 1, "arr" : [ { "a" : "a1", "b" : "b1" }, { "a" : "a2", "b" : "b2" } ] }
    { "_id" : 4, "arr" : [ { "a" : "a1", "b" : "b91" }, { "a" : "a29", "b" : "b1" } ] }
    

    So, using the $and operator is NOT intended for this purpose (i.e., querying on multiple fields of an array of sub-documents).

    Also, to query on an array embedded-document field (only one field) the $elemMatch is not required, for example:

    > db.arrays.find( { "arr.a": "a2" } )
    ==>
    { "_id" : 1, "arr" : [ { "a" : "a1", "b" : "b1" }, { "a" : "a2", "b" : "b2" } ] }
    { "_id" : 2, "arr" : [ { "a" : "a1", "b" : "b11" }, { "a" : "a2", "b" : "b22" } ] }
    { "_id" : 3, "arr" : [ { "a" : "a2", "b" : "b1" }, { "a" : "a", "b" : "b1" } ] }
    

提交回复
热议问题