【MongoDB系列】MongoDB 数组查询($elemMatch)
MongoDB系列】MongoDB 数组查询($elemMatch)
数组的查询多数情况结合$elemMatch
操作符一起查询,也可以不使用。
直接查询 (普通的find)
示例数据:
[
{ item: "journal", qty: 25, tags: ["blank", "red"], dim: [ 14, 21 ] },
{ item: "notebook", qty: 50, tags: ["red", "blank"], dim: [ 14, 21 ] },
{ item: "paper", qty: 100, tags: ["red", "blank", "plain"], dim: [ 14, 21 ] },
{ item: "planner", qty: 75, tags: ["blank", "red"], dim: [ 22.85, 30 ] },
{ item: "postcard", qty: 45, tags: ["blue"], dim: [ 10, 15.25 ] }
]
数组元素完全匹配查询
值、值的个数、顺序,都要完全一致才返回。
例如: db.inventory.find( { tags: ["red", "blank"] } )
,是查找tags数组下只且只有red/blank两个值的元素,且顺序要为red、blank。
数组元素部分匹配查询
只要数组元素中的值,部分值匹配要查询的条件,就可以返回,无关顺序,要使用 $all 操作符。
例如: db.inventory.find( { tags: { $all: ["red", "blank"] } } )
,查找tags数组中,只要元素值里面有red和blank(注意,是多个条件同时存在),就返回,无关顺序。
数组元素单个值匹配和范围查找
比如查找元素中包含某个值的文档,或者元素中存在位于查找范围区间的值的文档。
例如1: db.inventory.find( { tags: "red" } )
,查找元素中存在red值的文档,注意,这里不像上面的完全匹配或者部分匹配时使用中括号,而是直接把值带进去。
查找数组元素中存在符合区间范围的值的元素(类似部分匹配),一般会传入gt/lt/gte/lte/ne/eq之类的匹配范围操作符。
例如2:db.inventory.find( { dim_cm: { $gt: 25 } } )
,查找 dim_cm数组中,存在大于25的值的元素。
使用$elemMatch
操作符查询
$elemMatch
是用来查询数组字段的,如果数组字段中有至少1个元素匹配查询规则,则查询出来这个数组。
官方标准语法:
{ <field>: { $elemMatch: { <query1>, <query2>, ... } } }
// field是数组字段名,在$elemMatch中传入查询条件,可多个,用逗号隔开。
- 普通数组
示例数据:
[
{ _id: 1, results: [ 82, 85, 88 ] },
{ _id: 2, results: [ 75, 88, 89 ] }
]
查找 results数组中存在大于等于80且小于85的元素的文档。(只要元素中有一个匹配,那么这个元素所在的数组的文档就会返回)。
示例:db.scores.find({ results: { $elemMatch: { $gte: 80, $lt: 85 }}})
结果:{ "_id" : 1, "results" : [ 82, 85, 88 ] }
- 对象数组
示例数据:
[
{ "_id": 1, "results": [ { "product": "abc", "score": 10 },
{ "product": "xyz", "score": 5 } ] },
{ "_id": 2, "results": [ { "product": "abc", "score": 8 },
{ "product": "xyz", "score": 7 } ] },
{ "_id": 3, "results": [ { "product": "abc", "score": 7 },
{ "product": "xyz", "score": 8 } ] },
{ "_id": 4, "results": [ { "product": "abc", "score": 7 },
{ "product": "def", "score": 8 } ] }
]
查询results中元素含有 { product: "xyz", score: { gte: 8 } --- 也就是product = xyz, score ≥ 8的元素。 只要数组中的元素有至少一个匹配查询规则(elemMatch中的条件),那么该数组所在的文档就返回,不管数组中其他的元素怎样。
示例:db.survey.find({ results: { $elemMatch: { product: "xyz", score: { $gte: 8 }}}})
结果: "_id" : 3, "results" : [ { "product" : "abc", "score" : 7 }, { "product" : "xyz", "score" : 8 } ] }