Queries
A Query
is what is returned when calling many Model
methods. These Query
objects provide a chaining api to specify search terms, cursor options, hints, and other behavior.
Query#where
Lets you specify query terms with sugar.
query.where(path [, val])
path
is a valid document path. val
is optional. Its useful to omit val
when used in conjunction with other query methods. For example:
query
.where('name', 'Space Ghost')
.where('age').gte(21).lte(65)
.exec(callback)
In this case, gte()
and lte()
operate on the previous path if not explicitly passed. The above query results in the following query expression:
{ name: 'Space Ghost', age: { $gte: 21, $lte: 65 }}
Query#$where
Specifies the javascript function to run on MongoDB on each document scanned. See the MongoDB docs for details.
Model.find().$where(fn)
fn
can be either a function or a string.
Query#or
Specifies the $or operator.
query.or(array);
array
is an array of expressions.
query.or([{ color: 'blue' }, { color: 'red' }]);
Query#nor
Specifies the $nor operator.
query.nor(array);
array
is an array of expressions.
query.nor([{ color: 'daffodil yellow' }, { color: 'atomic tangerine' }]);
Query#equals
Assigns val
to the last path used in where()
.
query.where(path).equals(val)
// same as
query.where(path, val);
Query#gt
Specifies a greater than expression.
query.gt(path, val);
gt
is also one of the methods with extra chaining sugar: when only one argument is passed, it uses the path used the last call to where()
. Example:
Model.where('age').gt(21)
Results in:
{ age: { $gt: 21 }}
Query#gte
Specifies a greater than or equal to expression.
query.gte(path, val);
gte
is also one of the methods with extra chaining sugar: when only one argument is passed, it uses the path used the last call to where()
. Example:
Model.where('age').gte(21)
Results in:
{ age: { $gte: 21 }}
Query#lt
Specifies a less than expression.
query.lt(path, val);
lt
is also one of the methods with extra chaining sugar: when only one argument is passed, it uses the path used the last call to where()
. Example:
Model.where('age').lt(21)
Results in:
{ age: { $lt: 21 }}
Query#lte
Specifies a less than or equal to expression.
query.lte(path, val);
lte
is also one of the methods with extra chaining sugar: when only one argument is passed, it uses the path used the last call to where()
. Example:
Model.where('age').lte(21)
Results in:
{ age: { $lte: 21 }}
Query#ne
Specifies the $ne operator.
query.ne(path, val);
These methods have extra sugar in that when only one argument is passed, the path in the last call to where()
is used. Example:
query.where('_id').ne('4ecf92f31993a52c58e07f6a')
results in
{ _id: { $ne: ObjectId('4ecf92f31993a52c58e07f6a') }}
Query#in
Specifies the $in operator.
query.in(path, array)
This method has extra sugar in that when only one argument is passed, the path in the last call to where()
is used.
query.where('tags').in(['game', 'fun', 'holiday'])
results in
{ tags: { $in: ['game', 'fun', 'holiday'] }}
Query#nin
Specifies the $nin operator.
query.nin(path, array)
This method has extra sugar in that when only one argument is passed, the path in the last call to where()
is used.
query.where('games').nin(['boring', 'lame'])
results in
{ games: { $nin: ['boring', 'lame'] }}
Query#all
Specifies the $all operator.
query.all(path, array)
This method has extra sugar in that when only one argument is passed, the path in the last call to where()
is used.
query.where('games').all(['fun', 'exhausting'])
results in
{ games: { $all: ['fun', 'exhausting'] }}
Query#regex
Specifies the $regex operator.
query.regex('name.first', /^a/i)
This method has extra sugar in that when only one argument is passed, the path in the last call to where()
is used.
query.where('name.first').regex(/^a/i)
results in
{ 'name.first': { $regex: /^a/i }}
Query#size
Specifies the $size operator.
query.size(path, integer)
This method has extra sugar in that when only one argument is passed, the path in the last call to where()
is used.
query.size('comments', 2)
query.where('comments').size(2)
both result in
{ comments: { $size: 2 }}
Query#mod
Specifies the $mod operator.
var array = [10, 1]
query.mod(path, array)
query.mod(path, 10, 1)
query.where(path).mod(10, 1)
all result in
{ path: { $mod: [10, 1] }}
Query#exists
Specifies the $exists operator.
query.exists(path, Boolean)
These methods have extra sugar in that when only one argument is passed, the path from the last call to where()
is used.
Given the following query,
var query = Model.find();
the following queries
query.exists('occupation');
query.exists('occupation', true);
query.where('occupation').exists();
all result in
{ occupation: { $exists: true }}
Another example:
query.exists('occupation', false)
query.where('occupation').exists(false);
result in
{ occupation: { $exists: false }}
Query#elemMatch
Specifies the $elemMatch operator.
query.elemMatch(path, criteria)
query.where(path).elemMatch(criteria)
Functions can also be passed so you can further use query sugar to declare the expression:
query.where(path).elemMatch(function)
query.elemMatch(path, function)
In this case a query
is passed as the only argument into the function.
query.where('comments').elemMatch(function (elem) {
elem.where('author', 'bnoguchi')
elem.where('votes').gte(5);
});
Results in
{ comments: { $elemMatch: { author: 'bnoguchi', votes: { $gte: 5 }}}}
Query#within
query.within.box
query.within.center
todo
Query#box
todo
Query#center
todo
Query#centerSphere
todo
Query#near
Specifies the $near operator.
var array = [10, 1]
query.near(path, array)
query.near(path, 10, 1)
query.where(path).$near(10, 1)
all result in
{ path: { $near: [10, 1] }}
Query#maxDistance
Specifies the $maxDistance operator.
query.where('checkin').near([40, -72]).maxDistance(1);
results in
{ checkin: { $near: [40, -72], $maxDistance: 1 }}
Query#select
Specifies which subset of fields you want to return.
query.select('title name'})
// only _id, title, and name fields will be populated in your docs
You can also use object syntax:
query.select({ age: 0, contact: 0 })
// return everything but age and contact
Query#only
deprecated
Specifies a subset of fields to return. This is like select()
but this option only specifies which fields you want returned.
query.only('title name')
query.only('title', 'name')
query.only(['title', 'name'])
Query#exclude
deprecated
Specifies a subset of fields to return. This is like select()
but this option only specifies which fields you DO NOT want returned.
query.exclude('title name')
query.exclude('title', 'name')
query.exclude(['title', 'name'])
Query#slice
Retrieve a sub-range of elements in an array with the $slice method.
query.slice(path, val)
val
can be a Number:
query.where('tags').slice(5) // last 5 tags
query.where('tags').slice(-5) // first 5 tags
or an Array.
query.where('tags').slice([20, 10]) // skip 20, limit 10
query.where('tags').slice([-20, 10]) // 20 from the end, limit 10
slice
is also one of the methods with extra chaining sugar: when only one argument is passed, it uses the path used the last call to where()
. Example:
query.slice('tags', -5)
is the same as
query.where('tags').slice(-5)
Query#populate
Specifies the paths to be populated. See in-depth docs here.
Sorting
Query#sort
Sets the sort path and direction.
query.sort('path', 1)
query.sort('path', -1)
query.sort('path', 1, 'another.path', -1)
Query#asc
deprecated
Sorting sugar.
query.asc('path' [, paths])
Each string path
argument will be added to the sort ascending clause.
query.asc('title', 'name');
Is the same as
query.sort('title', 1).sort('name', 1);
Query#desc
deprecated
Sorting sugar.
query.desc('path' [, paths])
Each string path
argument will be added to the sort descending clause.
query.desc('title', 'name');
Is the same as
query.sort('title', -1, 'name', -1);
Options
Query#limit
The limit method specifies the max number of documents to return.
query.limit(20).skip(10)
Query#skip
The skip method specifies at which document the database should begin returning results.
query.skip(10).limit(20)
Query#maxscan
Limits the number of documents to scan.
query.maxscan(Number)
Query#snapshot
The snapshot method indicates the use of snapshot mode for the query.
query.snapshot(Boolean)
Query#batchSize
Sets the numer of documents to return per database query. For example, if we were qeurying for 10000 docs and streaming them to the client, we may want to limit the number of documents retrieved per cursor iteration to reduce memory consuption (all docs are held in memory during iteration). Setting batchSize
to, say, 100, would mean that the cursor would be pulling only 100 documents at a time from MongoDB.
query.batchSize(Number)
Query#slaveOk
Sets the slaveOk option or true
with no arguments.
query.slaveOk(Boolean)
query.slaveOk() // equivalent to query.slaveOk(true)
Query#tailable
Sets the tailable option or true
with no arguments.
query.tailable(Boolean)
query.tailable() // equivalent to query.tailable(true)
Tailable queries can only be used on capped collections, can only return documents in their natural order, and never use indexes. Unless the cursor dies, a tailable QueryStream will remain open and receive documents as they are inserted into the collection, much like the Unix tail -f
command.
var stream = Model.find().tailable().stream();
stream.on('data', function (doc) {
// do stuff
});
Query#hint
Specifies the hint option for MongoDB.
query.hint(indexName)
If your schema has an index like
Thing.index({ name: 1, title: 1 })
and you wanted to tell MongoDB to use that index for your query (in the off chance that MongoDB was not able to figure our that it should use it) you can give MongoDB a hint like so:
query.hint({ name: 1, title: 1}).exec(callback)
Query#comment
Sets the comment option.
query.comment(String)
Executing
Query#find
query.find(criteria [, callback])
Query#findOne
Sends the findOne command to MongoDB.
query.findOne([callback])
Query#count
Sends the count command to MongoDB.
query.count(callback)
Query#distinct
Casts field
and sends a distinct command to MongoDB.
query.distinct(field, callback)
Query#update
Casts the doc
according to the model Schema and sends an update command to MongoDB.
query.update(doc, callback)
All paths passed that are not $atomic operations will become $set ops so we retain backwards compatibility.
query.update({..}, { title: 'remove words' }, ...)
becomes
query.update({..}, { $set: { title: 'remove words' }}, ...)
Query#remove
Casts the query, then sends the remove command to MongoDB.
query.remove(callback)
Query#exec
Executes the query passing the results to the optional callback
.
query.exec([callback])
Typically used in chaining scenarios:
Model.findOne().where('points').$gt(1000).exec(function (err, doc) {
if (err) ...
});
Query#each
deprecated
A streaming cursor interface.
2.4.0 introduces the query.stream() method which is a more 'node-like' way of streaming records and provides better cursor management. It is recommended that you use query.stream in place of query.each.
query.each(callback);
The callback
is called repeatedly for each document found as its streamed. If an error occurs streaming stops.
query.each(function (err, user) {
if (err) return res.end("aww, received an error. all done.");
if (user) {
res.write(user.name + '\n')
} else {
res.end("reached end of cursor. all done.");
}
});
A third parameter may also be used in the callback which allows you to iterate the cursor manually.
query.each(function (err, user, next) {
if (err) return res.end("aww, received an error. all done.");
if (user) {
res.write(user.name + '\n')
doSomethingAsync(next);
} else {
res.end("reached end of cursor. all done.");
}
});
Query#stream
Returns a QueryStream for the query.
Model.find({}).stream().pipe(writeStream)
See the QueryStream docs for details.