假设我们有这些类型的文档:
{
"tags" : [
{
"fooObject" : {
"name" : "foo1"
},
"fooNumber" : 5,
"fooOther" : "foo"
},
{
"fooObject" : {
"name" : "foo2"
},
"fooNumber" : 4,
"fooOther" : "moo"
},
{
"fooObject" : {
"name" : "foo3"
},
"fooNumber" : 2,
"fooOther" : "goo"
}
]
}
我的实际查询是:
db.foes.find({'tags.fooObject.name': { $all: ['foo1','foo2'] })
所以我得到了包含"foo1"和"foo2"的文档。我想通过添加 fooNumber 来扩展此查询。我的意思是,在tags
层面上,成对进行比赛。我会传递一个带有标签的数组,但只指定fooObject
和fooNumber
,并获取包含这些标签的文档。
如果我要求
(foo1,5) and (foo2,4)
然后此文档将匹配。如果我要求
(foo1,4) and (foo2,4)
那么它就不匹配了。
我想你的意思是同一个数组元素中"名称"和"值"的"组合",整个数组都包含"两者"。因此,您需要在此处$elemMatch
$and
:
db.foes.find({
"$and": [
{ "tags": {
"$elemMatch": { "fooObject.name": "foo1", "fooNumber": 5 }
}},
{ "tags": {
"$elemMatch": { "fooObject.name": "foo2", "fooNumber": 4 }
}}
]
])
或者你甚至可以用$all
反过来写
db.foes.find({
"tags": { "$all": [
{ "$elemMatch": { "fooObject.name": "foo1", "fooNumber": 5 } },
{ "$elemMatch": { "fooObject.name": "foo2", "fooNumber": 4 } }
]}
})
这只会匹配"标签"中的数组元素满足"两个"条件的文档。
无论如何,$all
运算符在某种程度上是一种"缩短"形式的$and
。由于用于匹配奇异数组元素上的"对"条件的运算符是$elemMatch
,因此配对是自然的。