mongodb 是否有可能在聚合中获得单个结果?

yjghlzjz  于 2023-04-29  发布在  Go
关注(0)|答案(7)|浏览(148)

是否可以像在db.collection.findOne中那样在db.collection.aggregate上获得单个文档?

zf9nrax1

zf9nrax11#

是的,有可能。只需添加一个$group级,其中_id等于null。这将计算所有输入文档的累积值。例如:

{ $group: { _id: null, total: { $sum: "$price" }}}

或者,如果您只想从聚合结果中获取一个文档,可以使用$limit

{ $limit: 1 }

UPDATE:这两种解决方案都返回 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做同样的事情。例如:

> DBCollection.prototype.aggregateOne = function(pipeline) {
     var cur = this.aggregate(pipeline);
     if (!cur.hasNext())
         return null; 
     return cur.next(); 
 }

使用方法:

> db.collection.aggregateOne(...)
bvn4nwqk

bvn4nwqk2#

可以将$match级添加到聚合管道。但是即使它只匹配一个文档,结果仍然是一个列表(在这种情况下长度为1)。答案是“不,不可能”。

neskvpey

neskvpey3#

是的可以。你需要使用mongodb $match操作
这对我来说是有效的。

{ $lookup: { from: 'user', localField: 'userId', foreignField: 'id', as: 'publisherDetails' } },
{ $match: { id } }

mondodb doc's示例:

db.articles.aggregate(
[ { $match : { id : "132ada123aweae1321awew12" } },
  { $lookup: { from: 'user', localField: 'userId', foreignField: 'id', as: 'publisherDetails' } } ]
);
nxowjjhe

nxowjjhe4#

如果 "by a single result" 指的是findOne样式的返回类型,那么应该不可能这样做。虽然不是说这是不可能的,但它应该而且应该被视为不可能。聚合操作是documented,仅返回aggregate cursors,因此聚合操作的唯一可靠结论应该是aggregate cursorerror。当您收到聚合游标时,您就可以使用它的公开方法来访问单个文档。期待其他任何事情都类似于追求混乱。
PS:*******************************************************************************************************************************************************************************************************************************************************希望能帮助那些可能在这里结束的人。

jrcvhitl

jrcvhitl5#

在Python中,你可以将结果转换为一个列表并获取第一个元素:

result = list(mongo.db.collection.aggregate([{"$sample": {"size": 1}}]))[0]
icomxhvb

icomxhvb6#

只是为了用另一个简单的解决方案来改进答案,并避免编写大量重复的代码,这是我基于@Sergey别列佐夫斯基答案的解决方案。

import { Collection } from 'mongodb';

Collection.prototype.aggregateOne = async function(pipeline, options) {
   const items = await this.aggregate(pipeline, options).toArray();
   return items.length > 0 ? items[0] : null; 
}

就像普通的Aggregate函数一样,你可以这样使用:

return db.articles.aggregateOne(
   [ { $match : { id : "132ada123aweae1321awew12" } },
   { $lookup: { from: 'user', localField: 'userId', foreignField: 'id', as: 'publisherDetails' } } ]
);

这将返回第一个文档,如果存在或空。
希望这将有助于某人的生活。

xfb7svmp

xfb7svmp7#

我实际上使用的方法是collection.aggregate(pipeline).next()
对我来说那正是我想要的

相关问题