使用对象属性查询$all



假设我们有这些类型的文档:

{
    "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层面上,成对进行比赛。我会传递一个带有标签的数组,但只指定fooObjectfooNumber,并获取包含这些标签的文档。

如果我要求

(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,因此配对是自然的。

最新更新