mongodb如何获取具有相同键的每个“组”的最大值的文档

时间:2017-09-07 14:51:37

标签: mongodb pymongo

我有一个集合:

{'_id':'008','name':'ada','update':'1504501629','star':3.6,'desc':'ok', ...}
{'_id':'007','name':'bob','update':'1504501614','star':4.2,'desc':'gb', ...}
{'_id':'005','name':'ada','update':'1504501532','star':3.2,'desc':'ok', ...}
{'_id':'003','name':'bob','update':'1504501431','star':4.5,'desc':'bg', ...}
{'_id':'002','name':'ada','update':'1504501378','star':3.4,'desc':'no', ...}
{'_id':'001','name':'ada','update':'1504501325','star':3.6,'desc':'ok', ...}
{'_id':'000','name':'bob','update':'1504501268','star':4.3,'desc':'gg', ...}
...

如果我想要的结果是,同一'name'的'update'的最大值,意味着'name'的最新文档,得到整个文档:

{'_id':'008','name':'ada','update':'1504501629','star':3.6,'desc':'ok', ...}
{'_id':'007','name':'bob','update':'1504501614','star':4.2,'desc':'gb', ...}
...

如何最有效?

我现在在python中这样做:

result=[]
for name in db.collection.distinct('name'):
    result.append(db.collection.find({'name':name}).sort('update',-1)[0])

是否'找'过多次?

=====

我这样做是为了使用'name'抓取数据,获取许多其他密钥,每次插入文档时,我都会设置一个名为'update'的密钥。 当我使用数据库时,我想要特定“名称”的最新文档。所以它看起来不能只使用$ group。 我应该怎么做?重新设计数据库结构或更好的查找方法?

=====

改进了!
我试过创建'name'的索引& '更新',过程从半小时缩短到30秒!

但我仍然欢迎更好的解决方案^ _ ^

1 个答案:

答案 0 :(得分:0)

您的用例场景非常适合聚合。正如我在您的问题中看到的那样,您已经知道但无法弄清楚如何使用$group并获取具有最大更新的整个文档。如果您在$sort之前$group提交了文档,则可以使用$first运算符。因此,无需为每个名称发送查询查询。

db.collection.aggregate(
{ $sort: { "name": 1, "update": -1 } },
{ $group: { _id: "$name", "update": { $first: "$update" }, "doc_id": { $first: "$_id" } } }
)

我没有添加额外的$project操作进行汇总,您只需将结果中的字段添加到$group $first运算符即可。

此外,如果您仔细观察$sort操作,可以看到它使用您新创建的索引,因此您最好添加它,否则我也会推荐它:)

更新:对于您的评论中的问题:

您应该在$group中写下所有密钥。但是如果你认为它看起来很糟糕,或者将来会出现新的文件并且不希望每次都重写$group,我会这样做:

首先在聚合中获取所需文档的所有_id字段,然后使用find运算符在一个$in查询中获取这些文档。

db.collection.find( { "_id": { $in: [<ids returned in aggregation] } } )