$elemMatch
是 MongoDB 中用来查询内嵌文档的操作符。
创建一个简单文档
db.test.insert({
"id": 1,
"members": [
{
"name": "Jack",
"age": 27,
"gender": "M"
},
{
"name": "Tony",
"age": 23,
"gender": "F"
},
{
"name": "Lucy",
"age": 21,
"gender": "M"
}
]
})
使用多种方式尝试查询
a. 使用 db.test.find({"members": {"name": "Jack"}})
进行查询:
db.test.find({"members": {"name": "Jack"}})
查询的结果是空集。(因为 members 没有 name 字段)
b. 只有完全匹配一个的时候才能获取到结果,因此:
db.test.find({"members": {"name": "Jack", "age": 27, "gender": "M"}})
可以得到结果
c. 如果把键值进行颠倒,也得不到结果:
db.test.find({"members": {"name": "Jack", "gender": "M", "age": 27}})
得到的结果是空集。
d. 我们这样查询:
db.test.find({"members.name": "Jack"})
是可以查询出结果的。
e. 如果需要两个属性
db.test.find({"members.name": "Jack", "members.age": 27})
也可以查询结果。
f. 我们再进行破坏性测试
db.test.find({"members.name": "Jack", "members.age": 23})
也可以查询出结果。
不过我们应该注意到:Jack 是数组中第一个元素的键值,而 23 是数组中第二个元素的键值,这样也可以查询出结果。
使用 $elemMatch 操作符查询
对于我们的一些应用来说,以上结果显然不是我们想要的结果。所以我们应该使用 $elemMatch 操作符:
a. $elemMatch + 同一个元素中的键值组合
db.test.find({"members": {"$elemMatch": {"name": "Jack", "age": 27}}})
可以查询出结果。
b. $elemMatch + 不同元素的键值组合
db.test.find({"members": {"$elemMatch": {"name": "Jack", "age": 23}}})
查询不出结果。
因此,a 展示的嵌套查询正是我们想要的查询方式。