Difference in findOne() and find() while storing in some variable

1,297 views
Skip to first unread message

Abhishek kumar

unread,
Nov 20, 2011, 10:28:17 PM11/20/11
to mongodb-user
> x = db.collection.findOne()
> y = db.collection.find().limit(2)

when I tried to print the value of x and y, x is printing fine(as
expected ), but the value of y is nothing.

Also I wrote a stored procedure in which the function just returned,
db.collection.find().limit(2)

When I called db.eval("functionname()") from my application(in Java),
the output was,
{ "value" : "DBQuery: history.messages -> undefined"}

Though when stored JS function returns, db.collection.findOne() then
it is running fine

Some one please explain me why there is a difference.

Scott Hernandez

unread,
Nov 20, 2011, 10:36:25 PM11/20/11
to mongod...@googlegroups.com

Findone returns a single document and find returns a cursor, which you could convert to an array.

--
You received this message because you are subscribed to the Google Groups "mongodb-user" group.
To post to this group, send email to mongod...@googlegroups.com.
To unsubscribe from this group, send email to mongodb-user...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/mongodb-user?hl=en.

Abhishek kumar

unread,
Nov 20, 2011, 10:59:53 PM11/20/11
to mongodb-user
are you suggesting me to use, forEach() ??

I tried this and and I am getting the expected result,
my only question is why is this difference existing between
cursor(find()) and single document(findOne()). why I am not able to
store the cursor in a variable and later print the same value using
the variable.

On Nov 21, 8:36 am, Scott Hernandez <scotthernan...@gmail.com> wrote:
> Findone returns a single document and find returns a cursor, which you
> could convert to an array.

Scott Hernandez

unread,
Nov 21, 2011, 12:45:31 AM11/21/11
to mongod...@googlegroups.com
You can print the results, but a cursor doesn't actually have the
results, it just knows how to get the results from the server; it may
have some subset of the docs loaded at any time depending on if the
query has been run or not. In your case the query hasn't run until you
actually iterate through the first one.

You should convert the cursor to actual documents by calling toArray()
like this:
var docs = db.coll.find().toArray();

http://www.mongodb.org/display/DOCS/Queries+and+Cursors

Abhishek kumar

unread,
Nov 21, 2011, 2:01:07 AM11/21/11
to mongodb-user
Thanku scott, but
A slightly different doubt because of the answer that you given, "it

just knows how to get the results from the server"
What happens when do in my Application:

DBCursor cursor =
mongo.getCollection("collection_name").find().limit(2)
while(cursor.hasNext())
print(cursor.next());

Is it that everytime when cursor.next() is done, it goes to the server
and ask for the "next"
How then latency issues are handles if the implementation is like
above.
Please clarify where I am thinking wrong.. ??

Nat

unread,
Nov 21, 2011, 2:12:55 AM11/21/11
to mongod...@googlegroups.com
Cursor is lazily evaluated and each time next() is called, if there is no data available, it will retrieve a batch of results from the server (the number of results fetched depends on the size of the result set or the batchsize parameter). FindOne, to the server, is somewhat vaguely equivalent to find().limit(1).next().

Abhishek kumar

unread,
Nov 21, 2011, 2:10:43 AM11/21/11
to mongodb-user
Along with the above doubt, what I can see:

> x = db.messages.find().limit(2)
{ "_id" : ObjectId("4ec1172944ae943434c16939"), .................. }
> x
>
> x.hasNext()
false
>

so how can you tell that my query hasn't run, if it is, then why it is
displaying me the expected output ?

Nat

unread,
Nov 21, 2011, 2:54:42 AM11/21/11
to mongod...@googlegroups.com
That happened because when you are trying to evaluate find() in mongo shell REPL, it will iterate through cursor automatically to print the output. It shouldn't do so if you simply run a script that assign cursor to a variable.

You can check what being executed if you turn the profiler on from the server side.
-----Original Message-----
From: Abhishek kumar <abhishe...@gmail.com>
Sender: mongod...@googlegroups.com
Date: Sun, 20 Nov 2011 23:10:43
To: mongodb-user<mongod...@googlegroups.com>
Reply-To: mongod...@googlegroups.com
Subject: [mongodb-user] Re: Difference in findOne() and find() while storing
in some variable

Abhishek kumar

unread,
Nov 21, 2011, 4:03:34 AM11/21/11
to mongodb-user
Thank you for the clearance. Just one more doubt about the below
query(in my Java Application Server):

DBCursor cursor =
mongo.getCollection("collection_name").find().limit(2)

I am sure that cursor is not iterated. So, is it the case that when I
do cursor.next() it goes to the mongo server.

Or, every Object(in the result cursor) is returned to the Application
server and simply we do a cursor.next() and thus dont required to go
to the mongo server ??

Nat

unread,
Nov 21, 2011, 4:40:10 AM11/21/11
to mongod...@googlegroups.com
As I mentioned, it retrieves data in batch. You can profile and see how many query and getMore commands are issued.

Abhishek kumar

unread,
Nov 21, 2011, 8:52:11 AM11/21/11
to mongodb-user
can we change the batch size, what is the default batch size ?

Nat

unread,
Nov 21, 2011, 8:58:58 AM11/21/11
to mongod...@googlegroups.com
There is no default batch size. If not specfied, it will just try to fill up a buffer which I think it's around 4MB.(Not sure whether it has been changed in 2.0 or not)
Reply all
Reply to author
Forward
0 new messages