Aggregate constructor used for building aggregation pipelines. Do not instantiate this class directly, use Model.aggregate() instead.
const aggregate = Model.aggregate([
{ $project: { a: 1, b: 1 } },
{ $skip: 5 }
]);
Model.
aggregate([{ $match: { age: { $gte: 21 }}}]).
unwind('tags').
exec(callback);
_id
is a string in the database new Aggregate([{ $match: { _id: '00000000000000000000000a' } }]);
// Do this instead to cast to an ObjectId
new Aggregate([{ $match: { _id: mongoose.Types.ObjectId('00000000000000000000000a') } }]);
Returns an asyncIterator for use with for/await/of
loops You do not need to call this function explicitly, the JavaScript runtime will call it for you.
const agg = Model.aggregate([{ $match: { age: { $gte: 25 } } }]);
for await (const doc of agg) {
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 set if Symbol.asyncIterator
is undefined. If Symbol.asyncIterator
is undefined, that means your Node.js version does not support async iterators.
Sets an option on this aggregation. This function will be deprecated in a future release. Use the cursor()
, collation()
, etc. helpers to set individual options, or access agg.options
directly.
Note that MongoDB aggregations do not support the noCursorTimeout
flag, if you try setting that flag with this function you will get a "unrecognized field 'noCursorTimeout'" error.
Appends a new $addFields operator to this aggregate pipeline. Requires MongoDB v3.4+ to work
// adding new fields based on existing fields
aggregate.addFields({
newField: '$b.nested'
, plusTen: { $add: ['$val', 10]}
, sub: {
name: '$a'
}
})
// etc
aggregate.addFields({ salary_k: { $divide: [ "$salary", 1000 ] } });
Sets the allowDiskUse option for the aggregation query (ignored for < 2.6.0)
await Model.aggregate([{ $match: { foo: 'bar' } }]).allowDiskUse(true);
Appends new operators to this aggregate pipeline
aggregate.append({ $project: { field: 1 }}, { $limit: 2 });
// or pass an array
var pipeline = [{ $match: { daw: 'Logic Audio X' }} ];
aggregate.append(pipeline);
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.
Adds a collation
Model.aggregate(..).collation({ locale: 'en_US', strength: 1 }).exec();
Appends a new $count operator to this aggregate pipeline.
aggregate.count("userCount");
eachAsync()
and other query cursor semantics) Sets the cursor option option for the aggregation query (ignored for < 2.6.0). Note the different syntax below: .exec() returns a cursor object, and no callback is necessary.
var cursor = Model.aggregate(..).cursor({ batchSize: 1000 }).exec();
cursor.eachAsync(function(error, doc) {
// use doc
});
Executes the aggregate pipeline on the currently bound Model.
aggregate.exec(callback);
// Because a promise is returned, the `callback` is optional.
var promise = aggregate.exec();
promise.then(..);
Execute the aggregation with explain
Model.aggregate(..).explain(callback)
Combines multiple aggregation pipelines.
Model.aggregate(...)
.facet({
books: [{ groupBy: '$author' }],
price: [{ $bucketAuto: { groupBy: '$price', buckets: 2 } }]
})
.exec();
// Output: { books: [...], price: [{...}, {...}] }
Appends new custom $graphLookup operator(s) to this aggregate pipeline, performing a recursive search on a collection.
Note that graphLookup can only consume at most 100MB of memory, and does not allow disk use even if { allowDiskUse: true }
is specified.
// Suppose we have a collection of courses, where a document might look like `{ _id: 0, name: 'Calculus', prerequisite: 'Trigonometry'}` and `{ _id: 0, name: 'Trigonometry', prerequisite: 'Algebra' }`
aggregate.graphLookup({ from: 'courses', startWith: '$prerequisite', connectFromField: 'prerequisite', connectToField: 'name', as: 'prerequisites', maxDepth: 3 }) // this will recursively search the 'courses' collection up to 3 prerequisites
Appends a new custom $group operator to this aggregate pipeline.
aggregate.group({ _id: "$department" });
Sets the hint option for the aggregation query (ignored for < 3.6.0)
Model.aggregate(..).hint({ qty: 1, category: 1 }).exec(callback)
Appends a new $limit operator to this aggregate pipeline.
aggregate.limit(10);
Appends new custom $lookup operator(s) to this aggregate pipeline.
aggregate.lookup({ from: 'users', localField: 'userId', foreignField: '_id', as: 'users' });
Appends a new custom $match operator to this aggregate pipeline.
aggregate.match({ department: { $in: [ "sales", "engineering" ] } });
this
, otherwise will return the model Get/set the model that this aggregation will execute on.
const aggregate = MyModel.aggregate([{ $match: { answer: 42 } }]);
aggregate.model() === MyModel; // true
// Change the model. There's rarely any reason to do this.
aggregate.model(SomeOtherModel);
aggregate.model() === SomeOtherModel; // true
Appends a new $geoNear operator to this aggregate pipeline.
MUST be used as the first operator in the pipeline.
aggregate.near({
near: [40.724, -73.997],
distanceField: "dist.calculated", // required
maxDistance: 0.008,
query: { type: "public" },
includeLocs: "dist.location",
uniqueDocs: true,
num: 5
});
maxTimeMS
Aggregate.prototype.collation()
Aggregate.prototype.session()
Lets you set arbitrary options, for middleware or plugins.
var agg = Model.aggregate(..).option({ allowDiskUse: true }); // Set the `allowDiskUse` option
agg.options; // `{ allowDiskUse: true }`
Contains options passed down to the aggregate command.
readPreference
cursor
explain
allowDiskUse
maxTimeMS
bypassDocumentValidation
raw
promoteLongs
promoteValues
promoteBuffers
collation
comment
session
Returns the current pipeline
MyModel.aggregate().match({ test: 1 }).pipeline(); // [{ $match: { test: 1 } }]
Appends a new $project operator to this aggregate pipeline.
Mongoose query selection syntax is also supported.
// include a, include b, exclude _id
aggregate.project("a b -_id");
// or you may use object notation, useful when
// you have keys already prefixed with a "-"
aggregate.project({a: 1, b: 1, _id: 0});
// reshaping documents
aggregate.project({
newField: '$b.nested'
, plusTen: { $add: ['$val', 10]}
, sub: {
name: '$a'
}
})
// etc
aggregate.project({ salary_k: { $divide: [ "$salary", 1000 ] } });
Sets the readPreference option for the aggregation query.
Model.aggregate(..).read('primaryPreferred').exec(callback)
Sets the readConcern level for the aggregation query.
Model.aggregate(..).readConcern('majority').exec(callback)
Appends a new $redact operator to this aggregate pipeline.
If 3 arguments are supplied, Mongoose will wrap them with if-then-else of $cond operator respectively If thenExpr
or elseExpr
is string, make sure it starts with $$, like $$DESCEND
, $$PRUNE
or $$KEEP
.
Model.aggregate(...)
.redact({
$cond: {
if: { $eq: [ '$level', 5 ] },
then: '$$PRUNE',
else: '$$DESCEND'
}
})
.exec();
// $redact often comes with $cond operator, you can also use the following syntax provided by mongoose
Model.aggregate(...)
.redact({ $eq: [ '$level', 5 ] }, '$$PRUNE', '$$DESCEND')
.exec();
Appends a new $replaceRoot operator to this aggregate pipeline.
Note that the $replaceRoot
operator requires field strings to start with '$'. If you are passing in a string Mongoose will prepend '$' if the specified field doesn't start '$'. If you are passing in an object the strings in your expression will not be altered.
aggregate.replaceRoot("user");
aggregate.replaceRoot({ x: { $concat: ['$this', '$that'] } });
Appends new custom $sample operator(s) to this aggregate pipeline.
aggregate.sample(3); // Add a pipeline that picks 3 random documents
Sets the session for this aggregation. Useful for transactions.
const session = await Model.startSession();
await Model.aggregate(..).session(session);
Appends a new $skip operator to this aggregate pipeline.
aggregate.skip(10);
Appends a new $sort operator to this aggregate pipeline.
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.
// these are equivalent
aggregate.sort({ field: 'asc', test: -1 });
aggregate.sort('field -test');
Appends a new $sortByCount operator to this aggregate pipeline. Accepts either a string field name or a pipeline object.
Note that the $sortByCount
operator requires the new root to start with '$'. Mongoose will prepend '$' if the specified field name doesn't start with '$'.
aggregate.sortByCount('users');
aggregate.sortByCount({ $mergeObjects: [ "$employee", "$business" ] })
Provides promise for aggregate.
Model.aggregate(..).then(successCallback, errorCallback);
Appends new custom $unwind operator(s) to this aggregate pipeline.
Note that the $unwind
operator requires the path name to start with '$'. Mongoose will prepend '$' if the specified field doesn't start '$'.
aggregate.unwind("tags");
aggregate.unwind("a", "b", "c");
© 2010 LearnBoost
Licensed under the MIT License.
https://mongoosejs.com/docs/api/aggregate.html