通过mongodb聚合中的$max获取完整对象
我有一组需要按通过mongodb聚合中的$max获取完整对象,mongodb,aggregation-framework,Mongodb,Aggregation Framework,我有一组需要按masterID或id分组的对象,如果masterID不存在。对于具有相同masterID的一组对象,我需要找到具有最高pos属性的对象($max:“$pos”)。然而,我很难获得最大化pos的完整对象,似乎通过聚合我只能获得pos属性,而不能获得整个对象。下面是我使用的示例聚合,缺少masterID的$ifNull: > db.tst.aggregate([{ "$group": { "_id": "$masterID", "pos": { "$max": "$pos" }
masterID
或id
分组的对象,如果masterID
不存在。对于具有相同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
此问题表示应在按
pos
排序的对象上使用$first
或$last
,但我看不出如何返回整个对象。如果我理解正确,您可以尝试以下方法:
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
}
如果我理解正确,您可以尝试以下方法:
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
}
首先按
pos
降序排序。这样,每个masterID
遇到的第一个文档就是具有最高pos
的文档。您可以使用$$ROOT
引用管道中当前正在处理的整个文档
db.tst.aggregate([
{ "$sort" : { "pos" : -1 } },
{ "$group": {
"_id": { $ifNull: [ "$masterID", "$_id" ] },
"max_doc" : { "$first" : "$$ROOT" }
} }
])
首先按
pos
降序排序。这样,每个masterID
遇到的第一个文档就是具有最高pos
的文档。您可以使用$$ROOT
引用管道中当前正在处理的整个文档
db.tst.aggregate([
{ "$sort" : { "pos" : -1 } },
{ "$group": {
"_id": { $ifNull: [ "$masterID", "$_id" ] },
"max_doc" : { "$first" : "$$ROOT" }
} }
])
您需要先按
pos
排序,否则$first
值将来自的文档只是组中按自然顺序排列的第一个文档。您需要先按pos
排序,或者,$first
值将来自的文档只是组中按自然顺序排列的第一个文档。我不理解$$ROOT
。在$$ROOT
中,在$sort
之后有一个完整的文档?通过这种方式,您可以执行对象?$$ROOT
引用当前正在管道中处理的文档。请看,我不理解$$ROOT
。在$$ROOT
中,在$sort
之后有一个完整的文档?通过这种方式,您可以执行对象?$$ROOT
引用当前正在管道中处理的文档。看见