0

When And why use Cursor in your project?

If I have this Mock code

var mongoClient = require('mongodb').MongoClient;


mongoClient.connect('mongodb://localhost:27017/tut3',function(err,db){
    if(err)throw err;

    var collection = db.collection('messages');


    collection.find({},{_id:true}).each(function(err,doc){
        console.log("---- CLASSIC ----")
        console.dir(doc);
            //stuff//
    });

    var cursor = collection.find({},{_id:true});

    cursor.each(function(err,doc){
        console.log("---- CURSOR ----")
        console.dir(doc);
        //stuff2
    });

})

The collection messages is huge for example.

Which different between //stuffand //stuff2

I know that if I do

var cursor = collection.find({},{_id:true});

I Know that when cursor return I Have all the documents (synchronous) and it has many methods, but also inside stuff, the query is complete and I have all Documents...

Where is the difference? and when use var cursor instead the "classic" find?

2
  • What does "classic find" mean to you? The shell? That returns a cursor as well. The fact that the shell is a REPL is the reason you see results straight away, since it calls next for you and with a default "batch size" of 25. Commented Jul 24, 2014 at 7:17
  • No Sorry, I mean collection.find({},{_id:true}).each(function(err,doc){ with each inside a query. I know that it's a cursor. but i don't understand the difference between eachinside a query instead var cursor = query Commented Jul 24, 2014 at 7:20

1 Answer 1

1

The difference between

 cursor = collection.find();

and:

collection.find().each(function(err,doc) {

Is basically what is called "method chaining". It's really just an opinion of how you want to write your code. So what is being acted on with methods such as .each() is still just a cursor object that could have optionally be returned on the left hand side.

Also the "cursor" has not yet been "executed" until such a method is called. This means that "modifiers" can be applied without executing yet, as in:

cursor = cursor.skip(10);
cursor = cursor.limit(100);

As all modifiers will also return to the left a cursor.

This is essentially the principle applied in "method chaining", where whatever "type" is returned from the left can be "chained" on the right:

collection.find().skip(10).limit(100).each(function(err,doc) {

If you are dealing with "small" sets of results you can just call the .toArray() method on the cursor:

collection.find({},{_id:true}).toArray(function(err,array) {
   console.log( array ); // everything
});

But if have value 1000's or millions of results, you probably don't want to load all of that in memory. This is where you process with an iterator:

collection.find({},{_id:true}).each(function(err,doc) {
    // do something with the current doc
});

Iteration is why cursors exist.

Sign up to request clarification or add additional context in comments.

3 Comments

Perfect ! thanks You ! Last Question. In this code when I check count return ALL documents.Why? `
@PaulSantone Take a look at the manual page. .count() takes two arguments as in .count(applySkipLimit,callback). The default and what happens when the first is not supplied is the consideration is false and no modifier is applied. Basically what I said above, the cursor has not executed yet and only methods like .count() .each() .toArray() actually execute. .count(true,function(err,count) { applies any modifiers.
Thanks again! I had not seen in Doc. Thanks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.