MongoDB中的find()和findOne()方法显示不同的结果

时间:2016-10-21 04:33:36

标签: mongodb mongodb-query

我有一个Mongo数据库,在users集合中我只有1个文档。 我使用用户名过滤器执行<nav>This is the nav</nav> <main>This is the content</main>find()操作。 我从findOne()操作得到了我认为不正确的结果。

find()
  

请参阅MongoDB shell version: 3.2.10 connecting to: test Server has startup warnings: 2016-10-20T20:37:32.681-0700 I CONTROL [initandlisten] 2016-10-20T20:37:32.681-0700 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'. 2016-10-20T20:37:32.681-0700 I CONTROL [initandlisten] ** We suggest setting it to 'never' 2016-10-20T20:37:32.681-0700 I CONTROL [initandlisten] 2016-10-20T20:37:32.681-0700 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'. 2016-10-20T20:37:32.681-0700 I CONTROL [initandlisten] ** We suggest setting it to 'never' 2016-10-20T20:37:32.681-0700 I CONTROL [initandlisten] > use lab2 switched to db lab2 > db.users.find() { "_id" : ObjectId("5807ac0765f24dd0660e4332"), "username" : "avtrulzz", "fname" : "Abc", "lname" : "Def", "email" : "test@yahoo.co.in", "password" : "rootuser", "mobile" : NumberLong(1234567890) } > db.users.findOne() { "_id" : ObjectId("5807ac0765f24dd0660e4332"), "username" : "avtrulzz", "fname" : "Abc", "lname" : "Def", "email" : "test@yahoo.co.in", "password" : "rootuser", "mobile" : NumberLong(1234567890) } > if (db.users.find({username : "noSuchUsername"})) { ... print ("Username exists"); ... } else { ... print ("User does not exist"); } Username exists > if (db.users.findOne({username : "noSuchUsername"})) { print ("Username exists"); } else { print ("User does not exist"); } User does not exist > if (db.users.findOne({username : "avtrulzz"})) { print ("Username exists"); } else { print ("User does not exist"); } Username exists 操作返回用户是否存在,这是不正确的。 find()表现正常。enter image description here

5 个答案:

答案 0 :(得分:9)

首先,findOne()find()之间的基本区别:

  • findOne() - 如果查询匹配,则返回第一个文档,否则返回null。

  • find() - 匹配的文档数量最多,返回游标,永不为空。

因此,当置于if条件时,findOne()可以在不匹配任何文档时转换为false。当find返回一个游标对象并且永远不会返回null时,在置于if条件时将转换为true。

findfindOne()返回以下空集:

enter image description here

答案 1 :(得分:4)

你发现自己的陷阱是在javascript中从mongo shell对象转换为booleans的相当未记录的转换:

findOne()返回文档,或者nil / null /无论它被称为

find()返回光标,可以为空。但是返回的对象始终是定义的。

答案 2 :(得分:3)

find()方法返回cursor,即使查询条件与任何文档都不匹配,也始终为truthy

另一方面,findOne会返回与您的查询条件匹配的第一个文档null(JavaScript或您的语言驱动程序中的等效文档),如果没有任何符合指定标准的文件。

> db.dropDatabase()
{ "dropped" : "test", "ok" : 1 }
> var cursor = db.collection.find();
> cursor;
> typeof cursor;
object
> !cursor;
false
> var document = db.collection.findOne();
> document;
null
> typeof document;
object
> !document;
true

答案 3 :(得分:1)

也许find不是布尔检查的正确候选者,即使没有数据它返回一个空的游标,它在布尔值中传递为true

if (db.users.find({username : "noSuchUsername"}).toArray().length>0) {
... print ("Username exists"); 
... } else {
... print ("User does not exist"); }

   if (db.users.find({username : "noSuchUsername"}).size()>0) {
    ... print ("Username exists"); 
    ... } else {
    ... print ("User does not exist"); }

findOne工作正常,因为如果没有找到数据,则返回null,在布尔检查中传递为false。

答案 4 :(得分:1)

即使没有文档符合搜索条件,find()方法也将返回一个数组。空数组仍然存在,因此将成为真实的。

findOne()将仅返回一个文档,或者未定义。根据定义,未定义是虚假的值。

当您知道将仅搜索一个文档时,请使用findOne()获得更准确的表示形式。