Cursor Object: MongoDB


Lets have a deeper look into the MongoDB cursor object.

cursor-object-mongodb

Documents in our collection
test database, names collection.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
> use test
switched to db test
> show collections
names
system.indexes
> db.names.find();
{ "_id" : ObjectId("53be5d4604cc1cb0a7bfc3c0"), "name" : "Alia" }
{ "_id" : ObjectId("53be5d5204cc1cb0a7bfc3c1"), "name" : "Bebo" }
{ "_id" : ObjectId("53be5d5904cc1cb0a7bfc3c2"), "name" : "Chameli" }
{ "_id" : ObjectId("53be5d6104cc1cb0a7bfc3c3"), "name" : "Dev D" }
{ "_id" : ObjectId("53be5d6804cc1cb0a7bfc3c4"), "name" : "Emli" }
{ "_id" : ObjectId("53be5d8604cc1cb0a7bfc3c5"), "name" : "Farhan" }
{ "_id" : ObjectId("53be5d9204cc1cb0a7bfc3c6"), "name" : "Gangs" }
{ "_id" : ObjectId("53be5d9904cc1cb0a7bfc3c7"), "name" : "Hum" }
{ "_id" : ObjectId("53be5e3704cc1cb0a7bfc3c8"), "name" : 25 }

We have 8 documents with name in alphabetical order, and 1 document with name as 25. So in total we have 9 documents in our names collection.

Establishing Cursor

1
2
3
4
5
6
7
8
9
10
11
12
> var cur = db.names.find();
 
> cur
{ "_id" : ObjectId("53be5d4604cc1cb0a7bfc3c0"), "name" : "Alia" }
{ "_id" : ObjectId("53be5d5204cc1cb0a7bfc3c1"), "name" : "Bebo" }
{ "_id" : ObjectId("53be5d5904cc1cb0a7bfc3c2"), "name" : "Chameli" }
{ "_id" : ObjectId("53be5d6104cc1cb0a7bfc3c3"), "name" : "Dev D" }
{ "_id" : ObjectId("53be5d6804cc1cb0a7bfc3c4"), "name" : "Emli" }
{ "_id" : ObjectId("53be5d8604cc1cb0a7bfc3c5"), "name" : "Farhan" }
{ "_id" : ObjectId("53be5d9204cc1cb0a7bfc3c6"), "name" : "Gangs" }
{ "_id" : ObjectId("53be5d9904cc1cb0a7bfc3c7"), "name" : "Hum" }
{ "_id" : ObjectId("53be5e3704cc1cb0a7bfc3c8"), "name" : 25 }

Look at the contents of our cursor object cur.

hasNext() and next() methods on Cursor

1
2
3
4
5
6
7
8
9
> var cur = db.names.find();
> cur.hasNext();
true
> cur.next()
{ "_id" : ObjectId("53be5d4604cc1cb0a7bfc3c0"), "name" : "Alia" }
> cur.next()
{ "_id" : ObjectId("53be5d5204cc1cb0a7bfc3c1"), "name" : "Bebo" }
> cur.next()
{ "_id" : ObjectId("53be5d5904cc1cb0a7bfc3c2"), "name" : "Chameli" }

If there are any documents to iterate inside cursor object, then hasNext() will return true orelse it’ll return false. If hasNext() returns true, then we can iterate through the documents using next() method on the cursor object.

sort() method on Cursor Object

1
2
3
4
5
6
7
8
9
10
11
12
> var cur = db.names.find();
 
> cur.sort({"name": -1});
{ "_id" : ObjectId("53be5d9904cc1cb0a7bfc3c7"), "name" : "Hum" }
{ "_id" : ObjectId("53be5d9204cc1cb0a7bfc3c6"), "name" : "Gangs" }
{ "_id" : ObjectId("53be5d8604cc1cb0a7bfc3c5"), "name" : "Farhan" }
{ "_id" : ObjectId("53be5d6804cc1cb0a7bfc3c4"), "name" : "Emli" }
{ "_id" : ObjectId("53be5d6104cc1cb0a7bfc3c3"), "name" : "Dev D" }
{ "_id" : ObjectId("53be5d5904cc1cb0a7bfc3c2"), "name" : "Chameli" }
{ "_id" : ObjectId("53be5d5204cc1cb0a7bfc3c1"), "name" : "Bebo" }
{ "_id" : ObjectId("53be5d4604cc1cb0a7bfc3c0"), "name" : "Alia" }
{ "_id" : ObjectId("53be5e3704cc1cb0a7bfc3c8"), "name" : 25 }

We could modify the cursor object using methods like sort(), limit() and skip(). In above example, we are modifying cursor object using sort() method, and we are sorting it in reverse lexicographical order on the name field.

limit() method on Cursor Object

1
2
3
4
5
> var cur = db.names.find();
> cur.limit(3);
{ "_id" : ObjectId("53be5d4604cc1cb0a7bfc3c0"), "name" : "Alia" }
{ "_id" : ObjectId("53be5d5204cc1cb0a7bfc3c1"), "name" : "Bebo" }
{ "_id" : ObjectId("53be5d5904cc1cb0a7bfc3c2"), "name" : "Chameli" }

We could limit the output/result using limit() method.

Chaining method on Cursor Object

1
2
3
4
5
6
7
8
> var cur = db.names.find();
 
> cur.sort({"name": -1}).limit(5).skip(2);
{ "_id" : ObjectId("53be5d8604cc1cb0a7bfc3c5"), "name" : "Farhan" }
{ "_id" : ObjectId("53be5d6804cc1cb0a7bfc3c4"), "name" : "Emli" }
{ "_id" : ObjectId("53be5d6104cc1cb0a7bfc3c3"), "name" : "Dev D" }
{ "_id" : ObjectId("53be5d5904cc1cb0a7bfc3c2"), "name" : "Chameli" }
{ "_id" : ObjectId("53be5d5204cc1cb0a7bfc3c1"), "name" : "Bebo" }

Here we chain the methods sort(), limit() and skip(). We are sorting in reverse lexicographical order on the name field, then skipping the first 2 documents and then limiting the result/output to 5 documents.

The order in which these 3 methods are applied are: First sort, then skip and then limit.
Also note that, these methods modify cursor object at the server side and not on client site.

Cursor Object: MongoDB



YouTube Link: https://www.youtube.com/watch?v=_LexQW0vSlQ [Watch the Video In Full Screen.]



explain() method on Cursor Object

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
> db.names.find().explain();
{
        "cursor" : "BasicCursor",
        "isMultiKey" : false,
        "n" : 9,
        "nscannedObjects" : 9,
        "nscanned" : 9,
        "nscannedObjectsAllPlans" : 9,
        "nscannedAllPlans" : 9,
        "scanAndOrder" : false,
        "indexOnly" : false,
        "nYields" : 0,
        "nChunkSkips" : 0,
        "millis" : 0,
        "server" : "PC:27017",
        "filterSet" : false
}

explain() method shows that find() returns a basic cursor. More on explain() method in coming videos.

Programmatic way of printing Cursor Object content

1
2
3
4
5
6
7
8
9
10
11
12
> var cur = db.names.find();
 
> while(cur.hasNext()) printjson(cur.next());
{ "_id" : ObjectId("53be5d4604cc1cb0a7bfc3c0"), "name" : "Alia" }
{ "_id" : ObjectId("53be5d5204cc1cb0a7bfc3c1"), "name" : "Bebo" }
{ "_id" : ObjectId("53be5d5904cc1cb0a7bfc3c2"), "name" : "Chameli" }
{ "_id" : ObjectId("53be5d6104cc1cb0a7bfc3c3"), "name" : "Dev D" }
{ "_id" : ObjectId("53be5d6804cc1cb0a7bfc3c4"), "name" : "Emli" }
{ "_id" : ObjectId("53be5d8604cc1cb0a7bfc3c5"), "name" : "Farhan" }
{ "_id" : ObjectId("53be5d9204cc1cb0a7bfc3c6"), "name" : "Gangs" }
{ "_id" : ObjectId("53be5d9904cc1cb0a7bfc3c7"), "name" : "Hum" }
{ "_id" : ObjectId("53be5e3704cc1cb0a7bfc3c8"), "name" : 25 }

While loop executes until cur.hasNext() returns true. Until cur.hasNext() is true, cur.next() keeps printing next document in the cursor cur.

Leave a Reply

Your email address will not be published. Required fields are marked *