我有一个对象集合,如果不存在masterID
,则需要按masterID
或id
进行分组。在一组具有相同masterID
的对象中,我需要找到具有最高pos
属性($max: "$pos"
(的对象。但是,我很难获得pos
最大化的完整对象,似乎通过聚合我只能获得pos
属性,而不是整个对象。这是我使用的示例聚合,缺少masterID
$ifNull
:
> db.tst.aggregate([{ "$group": { "_id": "$masterID", "pos": { "$max": "$pos" } } }])
示例对象为:
> db.tst.find()
{ "_id" : ObjectId("547d6bd28e47d05a9a492e2e"), "masterID" : "master", "pos" : "453", "id" : "hallo" }
{ "_id" : ObjectId("547d6bda8e47d05a9a492e2f"), "masterID" : "master", "pos" : "147", "id" : "welt" }
{ "_id" : ObjectId("547d6be68e47d05a9a492e30"), "masterID" : "master2", "pos" : "1", "id" : "welt" }
所需的聚合结果为:
{ "_id" : ObjectId("547d6bd28e47d05a9a492e2e"), "masterID" : "master", "pos" : "453", "id" : "hallo" }
{ "_id" : ObjectId("547d6be68e47d05a9a492e30"), "masterID" : "master2", "pos" : "1", "id" : "welt" }
有没有办法通过聚合来实现这个结果,或者我是否需要使用 $push
来获取所有分组对象并在 Java 代码中围绕聚合实现pos
最大化?
这个问题mongodb聚合:如何返回一个带有min/max而不是值的对象,表明应该在按pos
排序的对象上使用$first
或$last
,但我看不出如何返回整个对象。
首先按pos
降序排序。这样,每个masterID
遇到的第一个文档就是pos
最高的文档。您可以使用$$ROOT
来引用管道中当前正在处理的整个文档。
db.tst.aggregate([
{ "$sort" : { "pos" : -1 } },
{ "$group": {
"_id": { $ifNull: [ "$masterID", "$_id" ] },
"max_doc" : { "$first" : "$$ROOT" }
} }
])
如果我理解正确,你可以试试这个:
db.tst.aggregate([
{ "$sort" : { "pos" : -1 } },
{
"$group": {
"_id": { $ifNull: [ "$masterID", "$id" ] },
"_Tempid":{$first:"$_id"},
"masterID":{$first:{ $ifNull: [ "$masterID", "$id" ] }},
"pos": { "$max": "$pos" },
"id" : {$first:"$id"}
}
},{
$project:{
_id:"$_Tempid",
"masterID":1,
"pos":1,
id:1
}
}
])
结果:
{
"result" : [
{
"_id" : ObjectId("547d6be68e47d05a9a492e30"),
"masterID" : "master2",
"pos" : "1",
"id" : "welt"
},
{
"_id" : ObjectId("547d6bd28e47d05a9a492e2e"),
"masterID" : "master",
"pos" : "453",
"id" : "hallo"
}
],
"ok" : 1
}