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

MongoDB中的find()和findOne()方法显示不同的结果,mongodb,mongodb-query,Mongodb,Mongodb Query,我有一个Mongo数据库,在users集合中我只有一个文档。 我使用用户名过滤器执行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-070

我有一个Mongo数据库,在users集合中我只有一个文档。 我使用用户名过滤器执行
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()
操作,该操作返回的是不正确的用户存在
findOne()
运行正常。

您发现自己陷入的陷阱是在javascript中从mongo shell对象到Boolean对象的转换没有记录在案:

findOne()返回一个文档,或nil/null/无论调用什么

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

即使查询条件与任何文档都不匹配,该方法也会返回一个始终为
truthy
的对象

另一方面,如果没有与指定条件匹配的文档,则返回与查询条件匹配的第一个文档,或者返回
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

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

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

  • find()
    -无论匹配的文档数有多少,都会返回一个游标,从不为null

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

find
findOne()
为空集合返回以下内容:


可能find不是布尔检查的正确候选项,即使没有数据,它也会返回一个空光标,在布尔值中作为true传递

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

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

find()方法将返回一个数组,即使没有与搜索条件匹配的文档。空数组仍然存在,因此它将充当truthy

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


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

您是说问题在于前两个查询(find()与findOne()的输出不同)还是最后一个命令(if块)的结果不同?输出结果会让您认为结果不正确吗?我认为find()还应该返回“User not exist”,因为没有名为“noSuchUsername”的用户不存在
   if (db.users.find({username : "noSuchUsername"}).size()>0) {
    ... print ("Username exists"); 
    ... } else {
    ... print ("User does not exist"); }