是否可以像db.collection.aggregate
一样在db.collection.findOne
上获取单个文档?
答案 0 :(得分:23)
是的,有可能。只需添加一个$group
阶段,_id
等于null
。这将计算所有输入文档的累计值。 E.g。
{ $group: { _id: null, total: { $sum: "$price" }}}
或者,如果您只想从汇总结果中获取一个文档,则可以使用$limit
:
{ $limit: 1 }
更新:这两个解决方案都返回 cursor ,它将包含单个文档。但是不要将findOne
视为特别的东西。它还检索游标并获取第一个文档(如果有的话)。这是findOne
的mongo shell实现:
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;
}
如您所见,它在内部使用find
。因此,如果您想获得单个文档而不是单个文档的光标,您可以编写自己的函数,该函数与aggregate
相同。 E.g。
> DBCollection.prototype.aggregateOne = function(pipeline) {
var cur = this.aggregate(pipeline);
if (!cur.hasNext())
return null;
return cur.next();
}
用法:
> db.collection.aggregateOne(...)
答案 1 :(得分:14)
可以将$match
阶段添加到聚合管道。但即使它只匹配一个文档,结果仍然是一个列表(在这种情况下长度为1)。所以答案是" NO ,这是不可能的"。
答案 2 :(得分:2)
例如:这对我有用。
{ $lookup: { from: 'user', localField: 'userId', foreignField: 'id', as: 'publisherDetails' } },
{ $match: { id } }
mondodb {{3}}示例:
db.articles.aggregate(
[ { $match : { id : "132ada123aweae1321awew12" } },
{ $lookup: { from: 'user', localField: 'userId', foreignField: 'id', as: 'publisherDetails' } } ]
);
答案 3 :(得分:1)
如果“单个结果” 是指findOne
样式的返回类型,则应该做到这一点。虽然没有说这是不可能的,但应该并且应该这样对待。聚合操作仅是documented才能返回aggregate cursors,因此聚合操作的唯一可靠结论应该是aggregate cursor
或error
。收到聚合游标后,您可以使用其公开的方法来访问单个文档。期待别的什么都类似于讨好混乱。
Ps:大量到达此线程。希望对以后可能会在这里遇到的其他人有所帮助。