mongodb - MongoDB:$elemMatch 和 $and 在数组中查找对象有什么区别?
问题描述
查询操作符的用法有什么逻辑上的区别吗$and
db.collection.find({$and: [{"array.field1": "someValue"}, {"array.field2": 3}]})
以及投影算子的使用$elemMatch
db.collection.find({array: {$elemMatch: {field1: "someValue", field2: 3}}})
查找包含数组内的对象字段的文档?
解决方案
我将用一个例子来解释这一点。考虑收藏arrays
。它有一个名为的字段arr
,它是一个嵌入文档的数组(带有字段a
和b
)。
集合中的一些文档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" } ] }
推荐阅读
- javascript - Expo Publish:请求失败,状态码为 413
- android - 三星 S7 没有;发现任何蓝牙设备
- python - 在 discord.py 中使用随机模块
- angular - HttpClient 不在服务上下文中发送令牌
- java - 使用 Cloud Run 进行服务器流式传输
- javascript - 选择包含嵌套子元素的元素
- python - 在模型上拟合数据时出错。目标输出需要匹配
- sql-server - 始终使用 sa 用户执行触发器
- angular - 如何对从服务订阅 EventEmitter 的 Angular 组件进行单元测试?
- c++ - 声明引用另一个枚举类的枚举类