Is it possible to get single result in aggregate?
Yes, it is possible. Just add a $group
stage with _id
equal to null
. That will calculate accumulated values for all the input documents as a whole. E.g.
{ $group: { _id: null, total: { $sum: "$price" }}}
Or if you want to get only one document from aggregated results, you can use $limit
:
{ $limit: 1 }
UPDATE: Both these solutions return cursor which would have single document. But don't think about findOne
as something special. It also retrieves cursor and just gets first document (if any). Here is mongo shell implementation of findOne
:
function ( query , fields, options ){
var cursor = this.find(query, fields, -1 /* limit */, 0 /* skip*/,
0 /* batchSize */, options);
if ( ! cursor.hasNext() )
return null;
var ret = cursor.next();
if ( cursor.hasNext() ) throw "findOne has more than 1 result!";
if ( ret.$err )
throw "error " + tojson( ret );
return ret;
}
As you can see, it internally uses find
. So, if you want to get single document instead of cursor with single document, you can write your own function which does same with aggregate
. E.g.
> DBCollection.prototype.aggregateOne = function(pipeline) {
var cur = this.aggregate(pipeline);
if (!cur.hasNext())
return null;
return cur.next();
}
Usage:
> db.collection.aggregateOne(...)
It is possible to add $match
stage to aggregation pipeline. But even if it will match only one single document, then result will still be a list (of length one in that case). So the answer is "NO, it is not possible".