$all
在$all
选择的文件,其中一个字段的值是包含所有指定元素的数组。要指定$all表达式,请使用以下原型:
1
|
{ <field>: { $all: [ <value1> , <value2> ... ] } }
|
特性
等效于$and操作
$all
相当于一个$and
指定的值的操作; 即以下语句:
1
|
{ tags: { $all: [ "ssl" , "security" ] } }
|
等效于:
1
|
{ $and: [ { tags: "ssl" }, { tags: "security" } ] }
|
嵌套数组
当传递嵌套数组(例如 [ [ "A" ] ]
)的数组时, 匹配文档,其中该字段包含嵌套数组作为元素(例如field: [ [ "A" ], ... ]
),或者该字段等于嵌套数组(例如field: [ "A" ]
)。
例如,考虑以下查询:
1
|
db.articles.find( { tags: { $all: [ [ "ssl", "security" ] ] } } )
|
该查询等效于:
1
|
db.articles.find( { $and: [ { tags: [ "ssl", "security" ] } ] } )
|
等效于:
1
|
db.articles.find( { tags: [ "ssl", "security" ] } )
|
因此,$all表达式匹配文档,其中tags字段是包含嵌套数组[ "ssl", "security" ]
的数组或等于嵌套数组的数组:
1
2
|
tags: [ [ "ssl", "security" ], ... ]
tags: [ "ssl", "security" ]
|
在$all
用表达单个元件是用于说明性的目的,因为$all
如果匹配仅单个元件的表达是不必要的。相反,当匹配单个元素时,“contains”表达式(即arrayField: element)更合适。
例子
以下示例使用inventory包含文档的集合:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
{
_id: ObjectId("5234cc89687ea597eabee675"),
code: "xyz",
tags: [ "school", "book", "bag", "headphone", "appliance" ],
qty: [
{ size: "S", num: 10, color: "blue" },
{ size: "M", num: 45, color: "blue" },
{ size: "L", num: 100, color: "green" }
]
}
{
_id: ObjectId("5234cc8a687ea597eabee676"),
code: "abc",
tags: [ "appliance", "school", "book" ],
qty: [
{ size: "6", num: 100, color: "green" },
{ size: "6", num: 50, color: "blue" },
{ size: "8", num: 100, color: "brown" }
]
}
{
_id: ObjectId("5234ccb7687ea597eabee677"),
code: "efg",
tags: [ "school", "book" ],
qty: [
{ size: "S", num: 10, color: "blue" },
{ size: "M", num: 100, color: "blue" },
{ size: "L", num: 100, color: "green" }
]
}
{
_id: ObjectId("52350353b2eff1353b349de9"),
code: "ijk",
tags: [ "electronics", "school" ],
qty: [
{ size: "M", num: 100, color: "green" }
]
}
|
使用$all以匹配值
以下操作使用$all操作者查询 inventory的文档集合,其中的值tags 字段是数组,其元素包括appliance,school,和 book:
1
|
db.inventory.find( { tags: { $all: [ "appliance", "school", "book" ] } } )
|
上面的查询返回以下文档:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
{
_id: ObjectId("5234cc89687ea597eabee675"),
code: "xyz",
tags: [ "school", "book", "bag", "headphone", "appliance" ],
qty: [
{ size: "S", num: 10, color: "blue" },
{ size: "M", num: 45, color: "blue" },
{ size: "L", num: 100, color: "green" }
]
}
{
_id: ObjectId("5234cc8a687ea597eabee676"),
code: "abc",
tags: [ "appliance", "school", "book" ],
qty: [
{ size: "6", num: 100, color: "green" },
{ size: "6", num: 50, color: "blue" },
{ size: "8", num: 100, color: "brown" }
]
}
|
$all
与使用`$elemMatch
如果该字段包含文件的数组,你可以使用 $all
与$elemMatch
操作。
以下操作在inventory集合中查询文档,其中qty字段的值是一个数组,其元素与$elemMatch条件匹配:
1
2
3
4
5
6
|
db.inventory.find( {
qty: { $all: [
{ "$elemMatch" : { size: "M", num: { $gt: 50} } },
{ "$elemMatch" : { num : 100, color: "green" } }
] }
} )
|
该查询返回以下文档:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
{
"_id" : ObjectId("5234ccb7687ea597eabee677"),
"code" : "efg",
"tags" : [ "school", "book"],
"qty" : [
{ "size" : "S", "num" : 10, "color" : "blue" },
{ "size" : "M", "num" : 100, "color" : "blue" },
{ "size" : "L", "num" : 100, "color" : "green" }
]
}
{
"_id" : ObjectId("52350353b2eff1353b349de9"),
"code" : "ijk",
"tags" : [ "electronics", "school" ],
"qty" : [
{ "size" : "M", "num" : 100, "color" : "green" }
]
}
|
存在该运算符$all
以支持对数组的查询。但是您可以使用$all
运算符来针对非数组进行选择 field,如以下示例所示:
1
|
db.inventory.find( { "qty.num": { $all: [ 50 ] } } )
|
但是,请使用以下形式表示相同的查询:
1
|
db.inventory.find( { "qty.num" : 50 } )
|
这两个查询都将选择inventory 集合中num字段值等于50的所有文档。
注意
在大多数情况下,MongoDB不会将数组视为集合。该运算符对此方法提供了明显的例外。
$elemMatch
$elemMatch匹配包含与匹配的所有指定的查询标准中的至少一个元素的数组字段的文档。
1
|
{ <field>: { $elemMatch: { <query1>, <query2>, ... } } }
|
如果仅在$elemMatch表达式中指定一个<query>
条件,则 无需使用 $elemMatch。
特性
- 您不能在中指定$where表达式 $elemMatch。
- 您不能在中指定$text查询表达式 $elemMatch。
例子
匹配元素
给定scores集合中的以下文件:
1
2
|
{ _id: 1, results: [ 82, 85, 88 ] }
{ _id: 2, results: [ 75, 88, 89 ] }
|
以下查询仅匹配results 数组包含至少一个大于或等于80且小于85的元素的那些文档。
1
2
3
|
db.scores.find(
{ results: { $elemMatch: { $gte: 80, $lt: 85 } } }
)
|
该查询返回以下文档,因为该元素82大于或等于80且小于85
1
|
{ "_id" : 1, "results" : [ 82, 85, 88 ] }
|
嵌入式文档数组
给定survey集合中的以下文件:
1
2
3
|
{ _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 } ] }
|
下面的查询仅那些文档,其中匹配results 数组包含与两个的至少一种元素product等于 “xyz"和score大于或等于8。
1
2
3
|
db.survey.find(
{ results: { $elemMatch: { product: "xyz", score: { $gte: 8 } } } }
)
|
具体来说,查询与以下文档匹配:
1
|
{ "_id" : 3, "results" : [ { "product" : "abc", "score" : 7 }, { "product" : "xyz", "score" : 8 } ] }
|
单查询条件
如果在$elemMatch
表达式中指定单个查询谓词,$elemMatch
则没有必要。
例如,考虑以下示例,其中$elemMatch 仅指定一个查询谓词:{ product: “xyz” }
1
2
3
|
db.survey.find(
{ results: { $elemMatch: { product: "xyz" } } }
)
|
由于$elemMatch仅指定一个条件,因此该 $elemMatch表达式不是必需的,而是可以使用以下查询:
1
2
3
|
db.survey.find(
{ "results.product": "xyz" }
)
|
$size
$size
匹配与由参数指定的元素数的任何数组。例如:
1
|
db.collection.find( { field: { $size: 2 } } );
|
返回collection其中where field是具有2个元素的数组的所有文档。例如,上面的表达式将返回{ field: [ red, green ] }
和{ field: [ apple, lime ] }
,但不会返回{ field: fruit }
或{ field: [ orange, lemon, grapefruit ] }
。要匹配数组中只有一个元素的字段,请使用值1,如下所示:
1
|
db.collection.find( { field: { $size: 1 } } );
|
$size
不接受值的范围。要基于元素数量不同的字段选择文档,请创建一个计数器字段,当您将元素添加到字段时该计数器字段会增加。
查询不能使用索引作为$size
查询的一部分,尽管查询的其他部分可以使用索引(如果适用)。