[SERVER-26718] find() v/s findOne() search on a single record Created: 21/Oct/16  Updated: 21/Oct/16  Resolved: 21/Oct/16

Status: Closed
Project: Core Server
Component/s: JavaScript, Querying
Affects Version/s: 3.2.10
Fix Version/s: None

Type: Question Priority: Minor - P4
Reporter: Anuvrat Tiku Assignee: David Storch
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Attachments: PNG File mongo_issue.png    
Participants:

 Description   

I have a Mongo database where in the users collection I have just 1 document. I do a find() and a findOne() operation using the username filter. I get what I think is an incorrect result from find() operation.

See the find operation is returning user exists which is not true. findOne() is behaving correctly.

> 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
> 



 Comments   
Comment by David Storch [ 21/Oct/16 ]

Hi avtrulzz,

Thanks for filing this issue! This is a consequence of find() and findOne() having different return types. findOne() issues a query with limit:1 to the server and returns the resulting document, or null if there is no document. find(), on the other hand, returns the shell's DBQuery which represents a cursor that can be iterated with hasNext() and next() methods. The DBQuery does not actually contact the server until the first invocation of hasNext() or next(). In your example above, "Username exists" is being printed simply because the DBQuery object is truthy. See the following example for a simpler demonstration of this:

> db.c.drop()
true
> db.c.insert({a: 1});
> var cursor = db.c.find({a: 2});
> if (cursor) { print("cursor is truthy"); }
cursor is truthy
> cursor.hasNext()
false

I am closing this ticket as Works as Designed.

Best,
Dave

Generated at Thu Feb 08 04:13:00 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.