首页 > 解决方案 > MongoDB:$elemMatch 和 $and 在数组中查找对象有什么区别?

问题描述

查询操作符的用法有什么逻辑上的区别吗$and

db.collection.find({$and: [{"array.field1": "someValue"}, {"array.field2": 3}]})

以及投影算子的使用$elemMatch

db.collection.find({array: {$elemMatch: {field1: "someValue", field2: 3}}})

查找包含数组内的对象字段的文档?

标签: mongodbmongodb-query

解决方案


我将用一个例子来解释这一点。考虑收藏arrays。它有一个名为的字段arr,它是一个嵌入文档的数组(带有字段ab)。

集合中的一些文档arrays

{ "_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" } ] }

我想找到所有带有数组嵌入文档字段a="a1"AND的文档b="b1"。请注意,这必须在数组的同一元素嵌入文档中。我为此使用$elemMatch并获得所需的结果。

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

现在,如果我在下面的查询中使用$and运算符,结果不正确。如您所见,已选择了一个附加文档。该查询使用数组嵌入文档字段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" } ] }

因此,使用$and运算符不适合此目的(即查询子文档数组的多个字段)。

此外,查询数组嵌入文档字段(只有一个字段$elemMatch不是必需的,例如:

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

推荐阅读