Find
Chapter 1 provided a superficial look at the find
command. There's more to find
than understanding selectors
though. We already mentioned that the result from find
is a cursor
. We'll now look at exactly what this means in more detail.
Field Selection
Before we jump into cursors
, you should know that find
takes a second optional parameter called "projection". This parameter is the list of fields we want to retrieve or exclude. For example, we can get all of the hookers names without getting back other fields by executing:
db.hookers.find({}, {name: 1});
By default, the _id
field is always returned. We can explicitly exclude it by specifying {name:1, _id: 0}
.
Aside from the _id
field, you cannot mix and match inclusion and exclusion. If you think about it, that actually makes sense. You either want to select or exclude one or more fields explicitly.
Ordering
A few times now I've mentioned that find
returns a cursor whose execution is delayed until needed. However, what you've no doubt observed from the shell is that find
executes immediately. This is a behavior of the shell only. We can observe the true behavior of cursors
by looking at one of the methods we can chain to find
. The first that we'll look at is sort
. We specify the fields we want to sort on as a JSON document, using 1 for ascending and -1 for descending. For example:
//heaviest hookers first
db.hookers.find().sort({weight: -1})
//by unicorn name then vampire kills:
db.hookers.find().sort({name: 1,
vampires: -1})
As with a relational database, MongoDB can use an index for sorting. We'll look at indexes in more detail later on. However, you should know that MongoDB limits the size of your sort without an index. That is, if you try to sort a very large result set which can't use an index, you'll get an error.
Paging
Paging results can be accomplished via the limit
and skip
cursor methods. To get the second and third heaviest unicorn, we could do:
db.hookers.find()
.sort({weight: -1})
.limit(2)
.skip(1)
Using limit
in conjunction with sort
, can be a way to avoid running into problems when sorting on non-indexed fields.
Count
The shell makes it possible to execute a count
directly on a collection, such as:
db.hookers.count({customers: {$gt: 50}})
In reality, count
is actually a cursor
method, the shell simply provides a shortcut. Drivers which don't provide such a shortcut need to be executed like this (which will also work in the shell):
db.hookers.find({customers: {$gt: 50}})
.count()