查询布尔型字段为“不正确”(例如,假或不存在)

我敢肯定,我在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有最好的答案。 $inselect器是最短和最干净的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)