当属性不存在时选择记录?

时间:2014-10-09 20:28:37

标签: mongodb mongodb-query

假设我有一个包含以下文档的集合:

{
    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}})

它什么都不返回。我的第二个查询不应该返回与第一个查询相同的结果

1 个答案:

答案 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 } 
        }
    }
})

因此强制将测试应用于数组元素,当然一个元素没有属性,因此至少有一个匹配并返回文档。