Query constructor used for building queries. You do not need to instantiate a Query
directly. Instead use Model functions like Model.find()
.
const query = MyModel.find(); // `query` is an instance of `Query`
query.setOptions({ lean : true });
query.collection(MyModel.collection);
query.where('age').gte(21).exec(callback);
// You can instantiate a query directly. There is no need to do
// this unless you're an advanced user with a very good reason to.
const query = new mongoose.Query();
Specifies a javascript function or expression to pass to MongoDBs query system.
query.$where('this.comments.length === 10 || this.name.length === 5')
// or
query.$where(function () {
return this.comments.length === 10 || this.name.length === 5;
})
Only use $where
when you have a condition that cannot be met using other MongoDB operators like $lt
. Be sure to read about all of its caveats before using.
Returns an asyncIterator for use with for/await/of
loops This function only works for find()
queries. You do not need to call this function explicitly, the JavaScript runtime will call it for you.
for await (const doc of Model.aggregate([{ $sort: { name: 1 } }])) {
console.log(doc.name);
}
Node.js 10.x supports async iterators natively without any flags. You can enable async iterators in Node.js 8.x using the --harmony_async_iteration
flag.
Note: This function is not if Symbol.asyncIterator
is undefined. If Symbol.asyncIterator
is undefined, that means your Node.js version does not support async iterators.
Specifies an $all
query condition.
When called with one argument, the most recent path passed to where()
is used.
MyModel.find().where('pets').all(['dog', 'cat', 'ferret']);
// Equivalent:
MyModel.find().all('pets', ['dog', 'cat', 'ferret']);
Specifies arguments for a $and
condition.
query.and([{ color: 'green' }, { status: 'ok' }])
Specifies the batchSize option.
query.batchSize(100)
Cannot be used with distinct()
Specifies a $box
condition
var lowerLeft = [40.73083, -73.99756]
var upperRight= [40.741404, -73.988135]
query.where('loc').within().box(lowerLeft, upperRight)
query.box({ ll : lowerLeft, ur : upperRight })
this.model
Casts this query to the schema of model
If obj
is present, it is cast instead of this query.
Executes the query returning a Promise
which will be resolved with either the doc(s) or rejected with the error. Like .then()
, but only takes a rejection handler.
DEPRECATED Specifies a $centerSphere
condition
Deprecated. Use circle instead.
var area = { center: [50, 50], radius: 10 };
query.where('loc').within().centerSphere(area);
Specifies a $center
or $centerSphere
condition.
var area = { center: [50, 50], radius: 10, unique: true }
query.where('loc').within().circle(area)
// alternatively
query.circle('loc', area);
// spherical calculations
var area = { center: [50, 50], radius: 10, unique: true, spherical: true }
query.where('loc').within().circle(area)
// alternatively
query.circle('loc', area);
Adds a collation to this op (MongoDB 3.4 and up)
Specifies the comment
option.
query.comment('login query')
Cannot be used with distinct()
Specifies this query as a count
query.
This method is deprecated. If you want to count the number of documents in a collection, e.g. count({})
, use the estimatedDocumentCount()
function instead. Otherwise, use the countDocuments()
function instead.
Passing a callback
executes the query.
This function triggers the following middleware.
count()
var countQuery = model.where({ 'color': 'black' }).count();
query.count({ color: 'black' }).count(callback)
query.count({ color: 'black' }, callback)
query.where('color', 'black').count(function (err, count) {
if (err) return handleError(err);
console.log('there are %d kittens', count);
})
Specifies this query as a countDocuments()
query. Behaves like count()
, except it always does a full collection scan when passed an empty filter {}
.
There are also minor differences in how countDocuments()
handles $where
and a couple geospatial operators. versus count()
.
Passing a callback
executes the query.
This function triggers the following middleware.
countDocuments()
const countQuery = model.where({ 'color': 'black' }).countDocuments();
query.countDocuments({ color: 'black' }).count(callback);
query.countDocuments({ color: 'black' }, callback);
query.where('color', 'black').countDocuments(function(err, count) {
if (err) return handleError(err);
console.log('there are %d kittens', count);
});
The countDocuments()
function is similar to count()
, but there are a few operators that countDocuments()
does not support. Below are the operators that count()
supports but countDocuments()
does not, and the suggested replacement:
$where
: $expr
$near
: $geoWithin
with $center
$nearSphere
: $geoWithin
with $centerSphere
Returns a wrapper around a mongodb driver cursor. A QueryCursor exposes a Streams3 interface, as well as a .next()
function.
The .cursor()
function triggers pre find hooks, but not post find hooks.
// There are 2 ways to use a cursor. First, as a stream:
Thing.
find({ name: /^hello/ }).
cursor().
on('data', function(doc) { console.log(doc); }).
on('end', function() { console.log('Done!'); });
// Or you can use `.next()` to manually get the next doc in the stream.
// `.next()` returns a promise, so you can use promises or callbacks.
var cursor = Thing.find({ name: /^hello/ }).cursor();
cursor.next(function(error, doc) {
console.log(doc);
});
// Because `.next()` returns a promise, you can use co
// to easily iterate through all documents without loading them
// all into memory.
co(function*() {
const cursor = Thing.find({ name: /^hello/ }).cursor();
for (let doc = yield cursor.next(); doc != null; doc = yield cursor.next()) {
console.log(doc);
}
});
transform
: optional function which accepts a mongoose document. The return value of the function will be emitted on data
and returned by .next()
.Query.prototype.setOptions()
Declare and/or execute this query as a deleteMany()
operation. Works like remove, except it deletes every document that matches filter
in the collection, regardless of the value of single
.
This function does not trigger any middleware
Character.deleteMany({ name: /Stark/, age: { $gte: 18 } }, callback)
Character.deleteMany({ name: /Stark/, age: { $gte: 18 } }).then(next)
This function calls the MongoDB driver's Collection#deleteMany()
function. The returned promise resolves to an object that contains 3 properties:
ok
: 1
if no errors occurreddeletedCount
: the number of documents deletedn
: the number of documents deleted. Equal to deletedCount
.const res = await Character.deleteMany({ name: /Stark/, age: { $gte: 18 } });
// `0` if no docs matched the filter, number of docs deleted otherwise
res.deletedCount;
Query.prototype.setOptions()
Declare and/or execute this query as a deleteOne()
operation. Works like remove, except it deletes at most one document regardless of the single
option.
This function does not trigger any middleware.
Character.deleteOne({ name: 'Eddard Stark' }, callback);
Character.deleteOne({ name: 'Eddard Stark' }).then(next);
This function calls the MongoDB driver's Collection#deleteOne()
function. The returned promise resolves to an object that contains 3 properties:
ok
: 1
if no errors occurreddeletedCount
: the number of documents deletedn
: the number of documents deleted. Equal to deletedCount
.const res = await Character.deleteOne({ name: 'Eddard Stark' });
// `1` if MongoDB deleted a doc, `0` if no docs matched the filter `{ name: ... }`
res.deletedCount;
Declares or executes a distinct() operation.
Passing a callback
executes the query.
This function does not trigger any middleware.
distinct(field, conditions, callback) distinct(field, conditions) distinct(field, callback) distinct(field) distinct(callback) distinct()
Specifies an $elemMatch
condition
query.elemMatch('comment', { author: 'autobot', votes: {$gte: 5}})
query.where('comment').elemMatch({ author: 'autobot', votes: {$gte: 5}})
query.elemMatch('comment', function (elem) {
elem.where('author').equals('autobot');
elem.where('votes').gte(5);
})
query.where('comment').elemMatch(function (elem) {
elem.where({ author: 'autobot' });
elem.where('votes').gte(5);
})
Specifies the complementary comparison value for paths specified with where()
User.where('age').equals(49);
// is the same as
User.where('age', 49);
exec()
will fail fast before sending the query to MongoDB Gets/sets the error flag on this query. If this flag is not null or undefined, the exec()
promise will reject without executing.
Query().error(); // Get current error value
Query().error(null); // Unset the current error
Query().error(new Error('test')); // `exec()` will resolve with test
Schema.pre('find', function() {
if (!this.getQuery().userId) {
this.error(new Error('Not allowed to query without setting userId'));
}
});
Note that query casting runs after hooks, so cast errors will override custom errors.
var TestSchema = new Schema({ num: Number });
var TestModel = db.model('Test', TestSchema);
TestModel.find({ num: 'not a number' }).error(new Error('woops')).exec(function(error) {
// `error` will be a cast error because `num` failed to cast
});
Specifies this query as a estimatedDocumentCount()
query. Faster than using countDocuments()
for large collections because estimatedDocumentCount()
uses collection metadata rather than scanning the entire collection.
estimatedDocumentCount()
does not accept a filter. Model.find({ foo: bar }).estimatedDocumentCount()
is equivalent to Model.find().estimatedDocumentCount()
This function triggers the following middleware.
estimatedDocumentCount()
await Model.find().estimatedDocumentCount();
Executes the query
var promise = query.exec();
var promise = query.exec('update');
query.exec(callback);
query.exec('find', callback);
Specifies an $exists
condition
// { name: { $exists: true }}
Thing.where('name').exists()
Thing.where('name').exists(true)
Thing.find().exists('name')
// { name: { $exists: false }}
Thing.where('name').exists(false);
Thing.find().exists('name', false);
Sets the explain
option, which makes this query return detailed execution stats instead of the actual query result. This method is useful for determining what index your queries use.
Calling query.explain(v)
is equivalent to query.setOption({ explain: v })
const query = new Query();
const res = await query.find({ a: 1 }).explain('queryPlanner');
console.log(res);
Find all documents that match selector
. The result will be an array of documents.
If there are too many documents in the result to fit in memory, use Query.prototype.cursor()
// Using async/await
const arr = await Movie.find({ year: { $gte: 1980, $lte: 1989 } });
// Using callbacks
Movie.find({ year: { $gte: 1980, $lte: 1989 } }, function(err, arr) {});
setOptions()
Declares the query a findOne operation. When executed, the first found document is passed to the callback.
Passing a callback
executes the query. The result of the query is a single document.
conditions
is optional, and if conditions
is null or undefined, mongoose will send an empty findOne
command to MongoDB, which will return an arbitrary document. If you're querying by _id
, use Model.findById()
instead.This function triggers the following middleware.
findOne()
var query = Kitten.where({ color: 'white' });
query.findOne(function (err, kitten) {
if (err) return handleError(err);
if (kitten) {
// doc may be null if no document matched
}
});
Issues a MongoDB findOneAndDelete command.
Finds a matching document, removes it, and passes the found document (if any) to the callback. Executes if callback
is passed.
This function triggers the following middleware.
findOneAndDelete()
This function differs slightly from Model.findOneAndRemove()
in that findOneAndRemove()
becomes a MongoDB findAndModify()
command, as opposed to a findOneAndDelete()
command. For most mongoose use cases, this distinction is purely pedantic. You should use findOneAndDelete()
unless you have a good reason not to.
sort
: if multiple docs are found by the conditions, sets the sort order to choose which doc to updatemaxTimeMS
: puts a time limit on the query - requires mongodb >= 2.6.0rawResult
: if true, resolves to the raw result from the MongoDB driver
function(error, doc) {
// error: any errors that occurred
// doc: the document before updates are applied if `new: false`, or after updates if `new = true`
}
A.where().findOneAndDelete(conditions, options, callback) // executes
A.where().findOneAndDelete(conditions, options) // return Query
A.where().findOneAndDelete(conditions, callback) // executes
A.where().findOneAndDelete(conditions) // returns Query
A.where().findOneAndDelete(callback) // executes
A.where().findOneAndDelete() // returns Query
Issues a mongodb findAndModify remove command.
Finds a matching document, removes it, passing the found document (if any) to the callback. Executes if callback
is passed.
This function triggers the following middleware.
findOneAndRemove()
sort
: if multiple docs are found by the conditions, sets the sort order to choose which doc to updatemaxTimeMS
: puts a time limit on the query - requires mongodb >= 2.6.0rawResult
: if true, resolves to the raw result from the MongoDB driver
function(error, doc) {
// error: any errors that occurred
// doc: the document before updates are applied if `new: false`, or after updates if `new = true`
}
A.where().findOneAndRemove(conditions, options, callback) // executes
A.where().findOneAndRemove(conditions, options) // return Query
A.where().findOneAndRemove(conditions, callback) // executes
A.where().findOneAndRemove(conditions) // returns Query
A.where().findOneAndRemove(callback) // executes
A.where().findOneAndRemove() // returns Query
Query.lean()
. undefined
when casting an update. In other words, if this is set, Mongoose will delete baz
from the update in Model.updateOne({}, { foo: 'bar', baz: undefined })
before sending the update to the server. Issues a MongoDB findOneAndReplace command.
Finds a matching document, removes it, and passes the found document (if any) to the callback. Executes if callback
is passed.
This function triggers the following middleware.
findOneAndReplace()
sort
: if multiple docs are found by the conditions, sets the sort order to choose which doc to updatemaxTimeMS
: puts a time limit on the query - requires mongodb >= 2.6.0rawResult
: if true, resolves to the raw result from the MongoDB driver
function(error, doc) {
// error: any errors that occurred
// doc: the document before updates are applied if `new: false`, or after updates if `new = true`
}
A.where().findOneAndReplace(filter, replacement, options, callback); // executes
A.where().findOneAndReplace(filter, replacement, options); // return Query
A.where().findOneAndReplace(filter, replacement, callback); // executes
A.where().findOneAndReplace(filter); // returns Query
A.where().findOneAndReplace(callback); // executes
A.where().findOneAndReplace(); // returns Query
Query.lean()
. undefined
when casting an update. In other words, if this is set, Mongoose will delete baz
from the update in Model.updateOne({}, { foo: 'bar', baz: undefined })
before sending the update to the server. rawResult
is used, in which case params are (error, writeOpResult) Issues a mongodb findAndModify update command.
Finds a matching document, updates it according to the update
arg, passing any options
, and returns the found document (if any) to the callback. The query executes if callback
is passed.
This function triggers the following middleware.
findOneAndUpdate()
new
: bool - if true, return the modified document rather than the original. defaults to false (changed in 4.0)upsert
: bool - creates the object if it doesn't exist. defaults to false.fields
: {Object|String} - Field selection. Equivalent to .select(fields).findOneAndUpdate()
sort
: if multiple docs are found by the conditions, sets the sort order to choose which doc to updatemaxTimeMS
: puts a time limit on the query - requires mongodb >= 2.6.0runValidators
: if true, runs update validators on this command. Update validators validate the update operation against the model's schema.setDefaultsOnInsert
: if this and upsert
are true, mongoose will apply the defaults specified in the model's schema if a new document is created. This option only works on MongoDB >= 2.4 because it relies on MongoDB's $setOnInsert
operator.rawResult
: if true, returns the raw result from the MongoDB driver
context
(string) if set to 'query' and runValidators
is on, this
will refer to the query in custom validator functions that update validation runs. Does nothing if runValidators
is false.function(error, doc) {
// error: any errors that occurred
// doc: the document before updates are applied if `new: false`, or after updates if `new = true`
}
query.findOneAndUpdate(conditions, update, options, callback) // executes
query.findOneAndUpdate(conditions, update, options) // returns Query
query.findOneAndUpdate(conditions, update, callback) // executes
query.findOneAndUpdate(conditions, update) // returns Query
query.findOneAndUpdate(update, callback) // returns Query
query.findOneAndUpdate(update) // returns Query
query.findOneAndUpdate(callback) // executes
query.findOneAndUpdate() // returns Query
type
property which is a String and a coordinates
property which is an Array. See the examples. Specifies a $geometry
condition
var polyA = [[[ 10, 20 ], [ 10, 40 ], [ 30, 40 ], [ 30, 20 ]]]
query.where('loc').within().geometry({ type: 'Polygon', coordinates: polyA })
// or
var polyB = [[ 0, 0 ], [ 1, 1 ]]
query.where('loc').within().geometry({ type: 'LineString', coordinates: polyB })
// or
var polyC = [ 0, 0 ]
query.where('loc').within().geometry({ type: 'Point', coordinates: polyC })
// or
query.where('loc').intersects().geometry({ type: 'Point', coordinates: polyC })
The argument is assigned to the most recent path passed to where()
.
geometry()
must come after either intersects()
or within()
.
The object
argument must contain type
and coordinates
properties. - type {String} - coordinates {Array}
For update operations, returns the value of a path in the update's $set
. Useful for writing getters/setters that can work with both update operations and save()
.
const query = Model.updateOne({}, { $set: { name: 'Jean-Luc Picard' } });
query.get('name'); // 'Jean-Luc Picard'
Returns the current query filter (also known as conditions) as a POJO.
const query = new Query();
query.find({ a: 1 }).where('b').gt(2);
query.getFilter(); // { a: 1, b: { $gt: 2 } }
Gets query options.
var query = new Query();
query.limit(10);
query.setOptions({ maxTimeMS: 1000 })
query.getOptions(); // { limit: 10, maxTimeMS: 1000 }
Gets a list of paths to be populated by this query
bookSchema.pre('findOne', function() {
let keys = this.getPopulatedPaths(); // ['author']
});
...
Book.findOne({}).populate('author');
// Deep populate
const q = L1.find().populate({
path: 'level2',
populate: { path: 'level3' }
});
q.getPopulatedPaths(); // ['level2', 'level2.level3']
Returns the current query filter. Equivalent to getFilter()
.
You should use getFilter()
instead of getQuery()
where possible. getQuery()
will likely be deprecated in a future release.
var query = new Query();
query.find({ a: 1 }).where('b').gt(2);
query.getQuery(); // { a: 1, b: { $gt: 2 } }
Returns the current update operations as a JSON object.
var query = new Query();
query.update({}, { $set: { a: 5 } });
query.getUpdate(); // { $set: { a: 5 } }
Specifies a $gt
query condition.
When called with one argument, the most recent path passed to where()
is used.
Thing.find().where('age').gt(21)
// or
Thing.find().gt('age', 21)
Specifies a $gte
query condition.
When called with one argument, the most recent path passed to where()
is used.
Sets query hints.
query.hint({ indexA: 1, indexB: -1})
Cannot be used with distinct()
Specifies an $in
query condition.
When called with one argument, the most recent path passed to where()
is used.
Declares an intersects query for geometry()
.
query.where('path').intersects().geometry({
type: 'LineString'
, coordinates: [[180.0, 11.0], [180, 9.0]]
})
query.where('path').intersects({
type: 'LineString'
, coordinates: [[180.0, 11.0], [180, 9.0]]
})
MUST be used after where()
.
In Mongoose 3.7, intersects
changed from a getter to a function. If you need the old syntax, use this.
Requests acknowledgement that this operation has been persisted to MongoDB's on-disk journal.
deleteOne()
deleteMany()
findOneAndDelete()
findOneAndReplace()
findOneAndUpdate()
remove()
update()
updateOne()
updateMany()
Defaults to the schema's writeConcern.j
option
await mongoose.model('Person').deleteOne({ name: 'Ned Stark' }).j(true);
Sets the lean option.
Documents returned from queries with the lean
option enabled are plain javascript objects, not Mongoose Documents. They have no save
method, getters/setters, virtuals, or other Mongoose features.
new Query().lean() // true
new Query().lean(true)
new Query().lean(false)
const docs = await Model.find().lean();
docs[0] instanceof mongoose.Document; // false
Lean is great for high-performance, read-only cases, especially when combined with cursors.
If you need virtuals, getters/setters, or defaults with lean()
, you need to use a plugin. See:
Specifies the maximum number of documents the query will return.
query.limit(20)
Cannot be used with distinct()
Specifies a $lt
query condition.
When called with one argument, the most recent path passed to where()
is used.
Specifies a $lte
query condition.
When called with one argument, the most recent path passed to where()
is used.
Runs a function fn
and treats the return value of fn
as the new value for the query to resolve to.
Any functions you pass to map()
will run after any post hooks.
const res = await MyModel.findOne().map(res => {
// Sets a `loadedAt` property on the doc that tells you the time the
// document was loaded.
return res == null ?
res :
Object.assign(res, { loadedAt: new Date() });
});
Specifies a maxDistance
query condition.
When called with one argument, the most recent path passed to where()
is used.
Specifies the maxScan option.
query.maxScan(100)
Cannot be used with distinct()
Sets the maxTimeMS option. This will tell the MongoDB server to abort if the query or write op has been running for more than ms
milliseconds.
Calling query.maxTimeMS(v)
is equivalent to query.setOption({ maxTimeMS: v })
const query = new Query();
// Throws an error 'operation exceeded time limit' as long as there's
// >= 1 doc in the queried collection
const res = await query.find({ $where: 'sleep(1000) || true' }).maxTimeMS(100);
DEPRECATED Alias of maxScan
Merges another Query or conditions object into this one.
When a Query is passed, conditions, field selection and options are merged.
divisor
, 2nd element is remainder
. Specifies a $mod
condition, filters documents for documents whose path
property is a number that is equal to remainder
modulo divisor
.
// All find products whose inventory is odd
Product.find().mod('inventory', [2, 1]);
Product.find().where('inventory').mod([2, 1]);
// This syntax is a little strange, but supported.
Product.find().where('inventory').mod(2, 1);
Getter/setter around the current mongoose-specific options for this query Below are the current Mongoose-specific options.
populate
: an array representing what paths will be populated. Should have one entry for each call to Query.prototype.populate()
lean
: if truthy, Mongoose will not hydrate any documents that are returned from this query. See Query.prototype.lean()
for more information.strict
: controls how Mongoose handles keys that aren't in the schema for updates. This option is true
by default, which means Mongoose will silently strip any paths in the update that aren't in the schema. See the strict
mode docs for more information.strictQuery
: controls how Mongoose handles keys that aren't in the schema for the query filter
. This option is false
by default for backwards compatibility, which means Mongoose will allow Model.find({ foo: 'bar' })
even if foo
is not in the schema. See the strictQuery
docs for more information.useFindAndModify
: used to work around the findAndModify()
deprecation warning
omitUndefined
: delete any properties whose value is undefined
when casting an update. In other words, if this is set, Mongoose will delete baz
from the update in Model.updateOne({}, { foo: 'bar', baz: undefined })
before sending the update to the server.nearSphere
: use $nearSphere
instead of near()
. See the Query.prototype.nearSphere()
docs
Mongoose maintains a separate object for internal options because Mongoose sends Query.prototype.options
to the MongoDB server, and the above options are not relevant for the MongoDB server.
Returns an object containing the Mongoose-specific options for this query, including lean
and populate
.
Mongoose-specific options are different from normal options (sort
, limit
, etc.) because they are not sent to the MongoDB server.
const q = new Query();
q.mongooseOptions().lean; // undefined
q.lean();
q.mongooseOptions().lean; // true
This function is useful for writing query middleware.
populate
lean
omitUndefined
strict
nearSphere
useFindAndModify
Specifies a $ne
query condition.
When called with one argument, the most recent path passed to where()
is used.
Specifies a $near
or $nearSphere
condition
These operators return documents sorted by distance.
query.where('loc').near({ center: [10, 10] });
query.where('loc').near({ center: [10, 10], maxDistance: 5 });
query.where('loc').near({ center: [10, 10], maxDistance: 5, spherical: true });
query.near('loc', { center: [10, 10], maxDistance: 5 });
DEPRECATED Specifies a $nearSphere
condition
query.where('loc').nearSphere({ center: [10, 10], maxDistance: 5 });
Deprecated. Use query.near()
instead with the spherical
option set to true
.
query.where('loc').near({ center: [10, 10], spherical: true });
Specifies an $nin
query condition.
When called with one argument, the most recent path passed to where()
is used.
Specifies arguments for a $nor
condition.
query.nor([{ color: 'green' }, { status: 'ok' }])
Specifies arguments for an $or
condition.
query.or([{ color: 'red' }, { status: 'emergency' }])
filter
. If not specified, orFail()
will throw a DocumentNotFoundError
Make this query throw an error if no documents match the given filter
. This is handy for integrating with async/await, because orFail()
saves you an extra if
statement to check if no document was found.
// Throws if no doc returned
await Model.findOne({ foo: 'bar' }).orFail();
// Throws if no document was updated
await Model.updateOne({ foo: 'bar' }, { name: 'test' }).orFail();
// Throws "No docs found!" error if no docs match `{ foo: 'bar' }`
await Model.find({ foo: 'bar' }).orFail(new Error('No docs found!'));
// Throws "Not found" error if no document was found
await Model.findOneAndUpdate({ foo: 'bar' }, { name: 'test' }).
orFail(() => Error('Not found'));
Specifies a $polygon
condition
query.where('loc').within().polygon([10,20], [13, 25], [7,15])
query.polygon('loc', [10,20], [13, 25], [7,15])
ref
field. populate()
retain null
and undefined
array entries. localField
. By default, Mongoose gets the raw value of localField
. For example, you would need to set this option to true
if you wanted to add a lowercase
getter to your localField
. BlogPost.find().populate('author')
, blog posts with the same author will share 1 copy of an author
doc. Enable this option to make Mongoose clone populated docs before assigning them. limit
and lean
. Specifies paths which should be populated with other documents.
Kitten.findOne().populate('owner').exec(function (err, kitten) {
console.log(kitten.owner.name) // Max
})
Kitten.find().populate({
path: 'owner',
select: 'name',
match: { color: 'black' },
options: { sort: { name: -1 } }
}).exec(function (err, kittens) {
console.log(kittens[0].owner.name) // Zoopa
})
// alternatively
Kitten.find().populate('owner', 'name', null, {sort: { name: -1 }}).exec(function (err, kittens) {
console.log(kittens[0].owner.name) // Zoopa
})
Paths are populated after the query executes and a response is received. A separate query is then executed for each path specified for population. After a response for each query has also been returned, the results are passed to the callback.
Get/set the current projection (AKA fields). Pass null
to remove the current projection.
Unlike projection()
, the select()
function modifies the current projection in place. This function overwrites the existing projection.
const q = Model.find();
q.projection(); // null
q.select('a b');
q.projection(); // { a: 1, b: 1 }
q.projection({ c: 1 });
q.projection(); // { c: 1 }
q.projection(null);
q.projection(); // null
Determines the MongoDB nodes from which to read.
primary - (default) Read from primary only. Operations will produce an error if primary is unavailable. Cannot be combined with tags.
secondary Read from secondary if available, otherwise error.
primaryPreferred Read from primary if available, otherwise a secondary.
secondaryPreferred Read from a secondary if available, otherwise read from the primary.
nearest All operations read from among the nearest candidates, but unlike other modes, this option will include both the primary and all secondaries in the random selection.
Aliases
p primary pp primaryPreferred s secondary sp secondaryPreferred n nearest
new Query().read('primary')
new Query().read('p') // same as primary
new Query().read('primaryPreferred')
new Query().read('pp') // same as primaryPreferred
new Query().read('secondary')
new Query().read('s') // same as secondary
new Query().read('secondaryPreferred')
new Query().read('sp') // same as secondaryPreferred
new Query().read('nearest')
new Query().read('n') // same as nearest
// read from secondaries with matching tags
new Query().read('s', [{ dc:'sf', s: 1 },{ dc:'ma', s: 2 }])
Sets the readConcern option for the query.
new Query().readConcern('local')
new Query().readConcern('l') // same as local
new Query().readConcern('available')
new Query().readConcern('a') // same as available
new Query().readConcern('majority')
new Query().readConcern('m') // same as majority
new Query().readConcern('linearizable')
new Query().readConcern('lz') // same as linearizable
new Query().readConcern('snapshot')
new Query().readConcern('s') // same as snapshot
local MongoDB 3.2+ The query returns from the instance with no guarantee guarantee that the data has been written to a majority of the replica set members (i.e. may be rolled back).
available MongoDB 3.6+ The query returns from the instance with no guarantee guarantee that the data has been written to a majority of the replica set members (i.e. may be rolled back).
majority MongoDB 3.2+ The query returns the data that has been acknowledged by a majority of the replica set members. The documents returned by the read operation are durable, even in the event of failure.
linearizable MongoDB 3.4+ The query returns data that reflects all successful majority-acknowledged writes that completed prior to the start of the read operation. The query may wait for concurrently executing writes to propagate to a majority of replica set members before returning results.
snapshot MongoDB 4.0+ Only available for operations within multi-document transactions. Upon transaction commit with write concern "majority", the transaction operations are guaranteed to have read from a snapshot of majority-committed data.
Aliases
l local a available m majority lz linearizable s snapshot
Read more about how to use read concern here.
Specifies a $regex
query condition.
When called with one argument, the most recent path passed to where()
is used.
Declare and/or execute this query as a remove() operation. remove()
is deprecated, you should use deleteOne()
or deleteMany()
instead.
This function does not trigger any middleware
Character.remove({ name: /Stark/ }, callback);
This function calls the MongoDB driver's Collection#remove()
function. The returned promise resolves to an object that contains 3 properties:
ok
: 1
if no errors occurreddeletedCount
: the number of documents deletedn
: the number of documents deleted. Equal to deletedCount
.const res = await Character.remove({ name: /Stark/ });
// Number of docs deleted
res.deletedCount;
Calling remove()
creates a Mongoose query, and a query does not execute until you either pass a callback, call Query#then()
, or call Query#exec()
.
// not executed
const query = Character.remove({ name: /Stark/ });
// executed
Character.remove({ name: /Stark/ }, callback);
Character.remove({ name: /Stark/ }).remove(callback);
// executed without a callback
Character.exec();
undefined
when casting an update. In other words, if this is set, Mongoose will delete baz
from the update in Model.updateOne({}, { foo: 'bar', baz: undefined })
before sending the update to the server. false
and schema-level timestamps are enabled, skip timestamps for this update. Does nothing if schema-level timestamps are not set. Declare and/or execute this query as a replaceOne() operation. Same as update()
, except MongoDB will replace the existing document and will not accept any atomic operators ($set
, etc.)
Note replaceOne will not fire update middleware. Use pre('replaceOne')
and post('replaceOne')
instead.
const res = await Person.replaceOne({ _id: 24601 }, { name: 'Jean Valjean' });
res.n; // Number of documents matched
res.nModified; // Number of documents modified
This function triggers the following middleware.
replaceOne()
Specifies which document fields to include or exclude (also known as the query "projection")
When using string syntax, prefixing a path with -
will flag that path as excluded. When a path does not have the -
prefix, it is included. Lastly, if a path is prefixed with +
, it forces inclusion of the path, which is useful for paths excluded at the schema level.
A projection must be either inclusive or exclusive. In other words, you must either list the fields to include (which excludes all others), or list the fields to exclude (which implies all other fields are included). The _id
field is the only exception because MongoDB includes it by default.
// include a and b, exclude other fields
query.select('a b');
// exclude c and d, include other fields
query.select('-c -d');
// Use `+` to override schema-level `select: false` without making the
// projection inclusive.
const schema = new Schema({
foo: { type: String, select: false },
bar: String
});
// ...
query.select('+foo'); // Override foo's `select: false` without excluding `bar`
// or you may use object notation, useful when
// you have keys already prefixed with a "-"
query.select({ a: 1, b: 1 });
query.select({ c: 0, d: 0 });
Determines if field selection has been made.
Determines if exclusive field selection has been made.
query.selectedExclusively() // false
query.select('-name')
query.selectedExclusively() // true
query.selectedInclusively() // false
Determines if inclusive field selection has been made.
query.selectedInclusively() // false
query.select('name')
query.selectedInclusively() // true
await conn.startSession()
Sets the MongoDB session associated with this query. Sessions are how you mark a query as part of a transaction.
Calling session(null)
removes the session from this query.
const s = await mongoose.startSession();
await mongoose.model('Person').findOne({ name: 'Axl Rose' }).session(s);
Adds a $set
to this query's update without changing the operation. This is useful for query middleware so you can add an update regardless of whether you use updateOne()
, updateMany()
, findOneAndUpdate()
, etc.
// Updates `{ $set: { updatedAt: new Date() } }`
new Query().updateOne({}, {}).set('updatedAt', new Date());
new Query().updateMany({}, {}).set({ updatedAt: new Date() });
Sets query options. Some options only make sense for certain operations.
The following options are only for find()
:
The following options are only for write operations: update()
, updateOne()
, updateMany()
, replaceOne()
, findOneAndUpdate()
, and findByIdAndUpdate()
:
timestamps
is set in the schema, set this option to false
to skip timestamps for that particular update. Has no effect if timestamps
is not enabled in the schema options.undefined
when casting an update. In other words, if this is set, Mongoose will delete baz
from the update in Model.updateOne({}, { foo: 'bar', baz: undefined })
before sending the update to the server.The following options are only for find()
, findOne()
, findById()
, findOneAndUpdate()
, and findByIdAndUpdate()
:
The following options are only for all operations except update()
, updateOne()
, updateMany()
, remove()
, deleteOne()
, and deleteMany()
:
The following options are for findOneAndUpdate()
and findOneAndRemove()
Sets the query conditions to the provided JSON object.
var query = new Query();
query.find({ a: 1 })
query.setQuery({ a: 2 });
query.getQuery(); // { a: 2 }
Sets the current update operation to new value.
var query = new Query();
query.update({}, { $set: { a: 5 } });
query.setUpdate({ $set: { b: 6 } });
query.getUpdate(); // { $set: { b: 6 } }
Specifies a $size
query condition.
When called with one argument, the most recent path passed to where()
is used.
MyModel.where('tags').size(0).exec(function (err, docs) {
if (err) return handleError(err);
assert(Array.isArray(docs));
console.log('documents with 0 tags', docs);
})
Specifies the number of documents to skip.
query.skip(100).limit(20)
Cannot be used with distinct()
DEPRECATED Sets the slaveOk option.
Deprecated in MongoDB 2.2 in favor of read preferences.
query.slaveOk() // true
query.slaveOk(true)
query.slaveOk(false)
Specifies a $slice
projection for an array.
query.slice('comments', 5)
query.slice('comments', -5)
query.slice('comments', [10, 5])
query.where('comments').slice(5)
query.where('comments').slice([-10, 5])
Specifies this query as a snapshot
query.
query.snapshot() // true
query.snapshot(true)
query.snapshot(false)
Cannot be used with distinct()
Sets the sort order
If an object is passed, values allowed are asc
, desc
, ascending
, descending
, 1
, and -1
.
If a string is passed, it must be a space delimited list of path names. The sort order of each path is ascending unless the path name is prefixed with -
which will be treated as descending.
// sort by "field" ascending and "test" descending
query.sort({ field: 'asc', test: -1 });
// equivalent
query.sort('field -test');
Cannot be used with distinct()
Sets the tailable option (for use with capped collections).
query.tailable() // true
query.tailable(true)
query.tailable(false)
Cannot be used with distinct()
Executes the query returning a Promise
which will be resolved with either the doc(s) or rejected with the error.
Converts this query to a customized, reusable query constructor with all arguments and options retained.
// Create a query for adventure movies and read from the primary
// node in the replica-set unless it is down, in which case we'll
// read from a secondary node.
var query = Movie.find({ tags: 'adventure' }).read('primaryPreferred');
// create a custom Query constructor based off these settings
var Adventure = query.toConstructor();
// Adventure is now a subclass of mongoose.Query and works the same way but with the
// default query parameters and options set.
Adventure().exec(callback)
// further narrow down our query results while still using the previous settings
Adventure().where({ name: /^Life/ }).exec(callback);
// since Adventure is a stand-alone constructor we can also add our own
// helper methods and getters without impacting global queries
Adventure.prototype.startsWith = function (prefix) {
this.where({ name: new RegExp('^' + prefix) })
return this;
}
Object.defineProperty(Adventure.prototype, 'highlyRated', {
get: function () {
this.where({ rating: { $gt: 4.5 }});
return this;
}
})
Adventure().highlyRated.startsWith('Life').exec(callback)
undefined
when casting an update. In other words, if this is set, Mongoose will delete baz
from the update in Model.updateOne({}, { foo: 'bar', baz: undefined })
before sending the update to the server. false
and schema-level timestamps are enabled, skip timestamps for this update. Does nothing if schema-level timestamps are not set. Declare and/or execute this query as an update() operation.
All paths passed that are not atomic operations will become $set
ops.
This function triggers the following middleware.
update()
Model.where({ _id: id }).update({ title: 'words' })
// becomes
Model.where({ _id: id }).update({ $set: { title: 'words' }})
upsert
(boolean) whether to create the doc if it doesn't match (false)multi
(boolean) whether multiple documents should be updated (false)runValidators
: if true, runs update validators on this command. Update validators validate the update operation against the model's schema.setDefaultsOnInsert
: if this and upsert
are true, mongoose will apply the defaults specified in the model's schema if a new document is created. This option only works on MongoDB >= 2.4 because it relies on MongoDB's $setOnInsert
operator.strict
(boolean) overrides the strict
option for this updateoverwrite
(boolean) disables update-only mode, allowing you to overwrite the doc (false)context
(string) if set to 'query' and runValidators
is on, this
will refer to the query in custom validator functions that update validation runs. Does nothing if runValidators
is false.read
writeConcern
Passing an empty object {}
as the doc will result in a no-op unless the overwrite
option is passed. Without the overwrite
option set, the update operation will be ignored and the callback executed without sending the command to MongoDB so as to prevent accidently overwritting documents in the collection.
The operation is only executed when a callback is passed. To force execution without a callback, we must first call update() and then execute it by using the exec()
method.
var q = Model.where({ _id: id }); q.update({ $set: { name: 'bob' }}).update(); // not executed q.update({ $set: { name: 'bob' }}).exec(); // executed // keys that are not [atomic](https://docs.mongodb.com/manual/tutorial/model-data-for-atomic-operations/#pattern) ops become `$set`. // this executes the same command as the previous example. q.update({ name: 'bob' }).exec(); // overwriting with empty docs var q = Model.where({ _id: id }).setOptions({ overwrite: true }) q.update({ }, callback); // executes // multi update with overwrite to empty doc var q = Model.where({ _id: id }); q.setOptions({ multi: true, overwrite: true }) q.update({ }); q.update(callback); // executed // multi updates Model.where() .update({ name: /^match/ }, { $set: { arr: [] }}, { multi: true }, callback) // more multi updates Model.where() .setOptions({ multi: true }) .update({ $set: { arr: [] }}, callback) // single update by default Model.where({ email: '[email protected]' }) .update({ $inc: { counter: 1 }}, callback)
API summary
update(filter, doc, options, cb) // executes
update(filter, doc, options)
update(filter, doc, cb) // executes
update(filter, doc)
update(doc, cb) // executes
update(doc)
update(cb) // executes
update(true) // executes
update()
undefined
when casting an update. In other words, if this is set, Mongoose will delete baz
from the update in Model.updateOne({}, { foo: 'bar', baz: undefined })
before sending the update to the server. false
and schema-level timestamps are enabled, skip timestamps for this update. Does nothing if schema-level timestamps are not set. Declare and/or execute this query as an updateMany() operation. Same as update()
, except MongoDB will update all documents that match filter
(as opposed to just the first one) regardless of the value of the multi
option.
Note updateMany will not fire update middleware. Use pre('updateMany')
and post('updateMany')
instead.
const res = await Person.updateMany({ name: /Stark$/ }, { isDeleted: true });
res.n; // Number of documents matched
res.nModified; // Number of documents modified
This function triggers the following middleware.
updateMany()
undefined
when casting an update. In other words, if this is set, Mongoose will delete baz
from the update in Model.updateOne({}, { foo: 'bar', baz: undefined })
before sending the update to the server. false
and schema-level timestamps are enabled, skip timestamps for this update. Does nothing if schema-level timestamps are not set. Declare and/or execute this query as an updateOne() operation. Same as update()
, except it does not support the multi
or overwrite
options.
filter
regardless of the value of the multi
option.replaceOne()
if you want to overwrite an entire document rather than using atomic operators like $set
.Note updateOne will not fire update middleware. Use pre('updateOne')
and post('updateOne')
instead.
const res = await Person.updateOne({ name: 'Jean-Luc Picard' }, { ship: 'USS Enterprise' });
res.n; // Number of documents matched
res.nModified; // Number of documents modified
This function triggers the following middleware.
updateOne()
Flag to opt out of using $geoWithin
.
mongoose.Query.use$geoWithin = false;
MongoDB 2.4 deprecated the use of $within
, replacing it with $geoWithin
. Mongoose uses $geoWithin
by default (which is 100% backward compatible with $within
). If you are running an older version of MongoDB, set this flag to false
so your within()
queries continue to work.
Sets the specified number of mongod
servers, or tag set of mongod
servers, that must acknowledge this write before this write is considered successful.
deleteOne()
deleteMany()
findOneAndDelete()
findOneAndReplace()
findOneAndUpdate()
remove()
update()
updateOne()
updateMany()
Defaults to the schema's writeConcern.w
option
// The 'majority' option means the `deleteOne()` promise won't resolve
// until the `deleteOne()` has propagated to the majority of the replica set
await mongoose.model('Person').
deleteOne({ name: 'Ned Stark' }).
w('majority');
Specifies a path
for use with chaining.
// instead of writing:
User.find({age: {$gte: 21, $lte: 65}}, callback);
// we can instead write:
User.where('age').gte(21).lte(65);
// passing query conditions is permitted
User.find().where({ name: 'vonderful' })
// chaining
User
.where('age').gte(21).lte(65)
.where('name', /^vonderful/i)
.where('friends').slice(10)
.exec(callback)
Defines a $within
or $geoWithin
argument for geo-spatial queries.
query.where(path).within().box()
query.where(path).within().circle()
query.where(path).within().geometry()
query.where('loc').within({ center: [50,50], radius: 10, unique: true, spherical: true });
query.where('loc').within({ box: [[40.73, -73.9], [40.7, -73.988]] });
query.where('loc').within({ polygon: [[],[],[],[]] });
query.where('loc').within([], [], []) // polygon
query.where('loc').within([], []) // box
query.where('loc').within({ type: 'LineString', coordinates: [...] }); // geometry
MUST be used after where()
.
As of Mongoose 3.7, $geoWithin
is always used for queries. To change this behavior, see Query.use$geoWithin.
In Mongoose 3.7, within
changed from a getter to a function. If you need the old syntax, use this.
If w > 1
, the maximum amount of time to wait for this write to propagate through the replica set before this operation fails. The default is 0
, which means no timeout.
deleteOne()
deleteMany()
findOneAndDelete()
findOneAndReplace()
findOneAndUpdate()
remove()
update()
updateOne()
updateMany()
Defaults to the schema's writeConcern.wtimeout
option
// The `deleteOne()` promise won't resolve until this `deleteOne()` has
// propagated to at least `w = 2` members of the replica set. If it takes
// longer than 1 second, this `deleteOne()` will fail.
await mongoose.model('Person').
deleteOne({ name: 'Ned Stark' }).
w(2).
wtimeout(1000);
© 2010 LearnBoost
Licensed under the MIT License.
https://mongoosejs.com/docs/api/query.html