我有一个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()
表现正常。
答案 0 :(得分:9)
首先,findOne()
和find()
之间的基本区别:
findOne()
- 如果查询匹配,则返回第一个文档,否则返回null。
find()
- 匹配的文档数量最多,返回游标,永不为空。
因此,当置于if条件时,findOne()
可以在不匹配任何文档时转换为false。当find返回一个游标对象并且永远不会返回null时,在置于if条件时将转换为true。
find
和findOne()
返回以下空集:
答案 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()获得更准确的表示形式。