假设我有一个包含以下文档的集合:
{
title: "test1",
items:
[
{id: 1, sub_id: 23, value:"some value"},
{id: 2, value:"some value"}
]
},
{
title: "test2",
items:
[
{id: 4, sub_id: 34, value:"blah"},
{id: 5, sub_id: 56, value:"whatever"},
]
}
我想选择属性sub_id
不存在的位置,id
属性确实存在。如果我运行查询:
db.myCollection.find({"items.sub_id": {$exists: false}})
它返回我想要的记录(标题为test1
的文档),但是当我运行此查询时:
db.myCollection.find({"items.sub_id": {$exists: false}, "items.id": {$exists:true}})
它什么都不返回。我的第二个查询不应该返回与第一个查询相同的结果
答案 0 :(得分:1)
实际上,您的第一个查询无法返回您提供的示例的结果。原因是这两个文档都没有没有数组元素,不包含" sub_id"属性。所以在第一个文档中,虽然第二个数组元素缺少属性,但第一个数组元素确实有一个属性,因此条件实际上是假的。 $exists
和假测试有点奇怪。
因此,为了使这项工作,您需要比较各个数组元素的条件。这意味着您需要$elemMatch
运算符:
db.myCollection.find({
"items": {
"$elemMatch": {
"id": { "$exists": true },
"sub_id": { "$exists": false }
}
}
})
并且正确地选择具有数组元素的文档,其中存在" id"属性但没有" sub_id"属性。
由于$exists
遍历文档以匹配条件的方式,同样适用于单个元素,因此您只使用$elemMatch
一个案例字段:
db.myCollection.find({
"items": {
"$elemMatch": {
"sub_id": { "$exists": false }
}
}
})
因此强制将测试应用于数组元素,当然一个元素没有属性,因此至少有一个匹配并返回文档。