MongoDB $elemMatch 操作符.md

$elemMatch 是 MongoDB 中用来查询内嵌文档的操作符。

创建一个简单文档

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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"}}) 进行查询:

1
db.test.find({"members": {"name": "Jack"}})

查询的结果是空集。(因为 members 没有 name 字段)

b. 只有完全匹配一个的时候才能获取到结果,因此:

1
db.test.find({"members": {"name": "Jack", "age": 27, "gender": "M"}})

可以得到结果

c. 如果把键值进行颠倒,也得不到结果:

1
db.test.find({"members": {"name": "Jack", "gender": "M", "age": 27}})

得到的结果是空集。

d. 我们这样查询:

1
db.test.find({"members.name": "Jack"})

是可以查询出结果的。

e. 如果需要两个属性

1
db.test.find({"members.name": "Jack", "members.age": 27})

也可以查询结果。

f. 我们再进行破坏性测试

1
db.test.find({"members.name": "Jack", "members.age": 23})

也可以查询出结果。

不过我们应该注意到:Jack 是数组中第一个元素的键值,而 23 是数组中第二个元素的键值,这样也可以查询出结果。

使用 $elemMatch 操作符查询

对于我们的一些应用来说,以上结果显然不是我们想要的结果。所以我们应该使用 $elemMatch 操作符:

a. $elemMatch + 同一个元素中的键值组合

1
db.test.find({"members": {"$elemMatch": {"name": "Jack", "age": 27}}})

可以查询出结果。

b. $elemMatch + 不同元素的键值组合

1
db.test.find({"members": {"$elemMatch": {"name": "Jack", "age": 23}}})

查询不出结果。

因此,a 展示的嵌套查询正是我们想要的查询方式。