查询布尔型字段为“不正确”(例如,假或不存在)
我敢肯定,我在MongoDB查询中缺less一些非常基本的东西,似乎无法得到这个简单的条件。
考虑这个集合
> db.tests.find() { "_id" : ObjectId("..."), "name" : "Test1" , "deleted" : true} { "_id" : ObjectId("..."), "name" : "Test2" , "deleted" : false} { "_id" : ObjectId("..."), "name" : "Test3" }
我只想查询所有“未删除”的项目
我知道如何find具有“已删除”标志设置为真的项目:
> db.tests.find({deleted:true}) { "_id" : ObjectId("..."), "name" : "Test1" , "deleted" : true}
但是,如何find所有不被"deleted"
(例如,否定上述查询,或者换句话说,任何没有"deleted"
字段的项目,或者使其值为false
我猜的是什么 (请不要笑)
> db.tests.find({$not : {deleted: true}})
(不返回结果)
> db.tests.find({$not : {$eq:{deleted:true}}})
错误:{“$ err”:“无效的操作符:$ eq”,“code”:10068}
> db.tests.find({deleted:{$not: true}})
错误:{“$ err”:“无效使用$ not”,“code”:13041}
> db.tests.find({deleted:{$not: {$eq:true}}})
错误:{“$ err”:“非法使用$ not”,“code”:13034}
我错过了什么?
db.tests.find({deleted: {$ne: true}})
$ne
代表“不等于”。 ( 有关MongoDB运算符的文档 )
为了完整起见,另一种方法是使用$in
:
db.test.find({deleted: {$in: [null, false]}})
在数组中包含null
拉入deleted
字段丢失的文档。 此查询可以在当前的2.6.6 MongoDB版本中的{deleted: 1}
上使用索引。
JohnnyHK有最好的答案。 $in
select器是最短和最干净的IMO。
这将testing完全“假”或“不存在”。 并可以被索引。
db.tests.find({$or:[{deleted:false},{deleted:{$exists:false}}]})
一个使用索引的例子。
((function(){ print("creating collection 'testx' and inserting 50 trues, 50 falses, 50 non-existents"); db.testx.drop(); db.testx.ensureIndex({deleted:1}); for (var i=0;i<50;i++){ db.testx.insert({i:i,deleted:false}); }; for (var i=0;i<50;i++){ db.testx.insert({i:i,deleted:true}); }; for (var i=0;i<50;i++){ db.testx.insert({i:i}); }; var res0 = db.testx.find().explain(); var res1 = db.testx.find({deleted:false}).explain(); var res2 = db.testx.find({deleted:true}).explain(); var res3 = db.testx.find({deleted:{$exists:false}}).explain(); var res4 = db.testx.find({$or:[{deleted:false},{deleted:{$exists:false}}]}).explain(); var res5 = db.testx.find({$or:[{deleted:true},{deleted:{$exists:false}}]}).explain(); var res6 = db.testx.find({deleted:{$in:[false,null]}}).explain(); print("res0: all objects ("+res0["n"]+" found, "+res0["nscannedObjects"]+" scanned)"); print("res1: deleted is false ("+res1["n"]+" found, "+res1["nscannedObjects"]+" scanned)"); print("res2: deleted is true ("+res2["n"]+" found, "+res2["nscannedObjects"]+" scanned)"); print("res3: deleted is non-existent ("+res3["n"]+" found, "+res3["nscannedObjects"]+" scanned)"); print("res4: deleted is false or non-existent ("+res4["n"]+" found, "+res4["nscannedObjects"]+" scanned)"); print("res5: deleted is true or non-existent ("+res5["n"]+" found, "+res5["nscannedObjects"]+" scanned)"); print("res6: deleted is in [false,null] ("+res5["n"]+" found, "+res5["nscannedObjects"]+" scanned)"); })())
这应该打印
creating collection 'testx' and inserting 50 trues, 50 falses, 50 non-existents res0: all objects (150 found, 150 scanned) res1: deleted is false (50 found, 50 scanned) res2: deleted is true (50 found, 50 scanned) res3: deleted is non-existent (50 found, 50 scanned) res4: deleted is false or non-existent (100 found, 100 scanned) res5: deleted is true or non-existent (100 found, 100 scanned) res6: deleted is in [false,null] (100 found, 100 scanned)