mongodb - MongoDb 聚合分组和排序应用程序
问题描述
有结构的文件:
{"appId":<id>,"time":<number>}
对于这个例子,我们假设我们有:
{"appId":"A","time":1}
{"appId":"A","time":3}
{"appId":"A","time":5}
{"appId":"B","time":1}
{"appId":"B","time":2}
{"appId":"B","time":4}
{"appId":"B","time":6}
是否可以按 appId 对文档进行分组,每个组按时间排序,以及从该组的最新时间显示的所有结果,例如:
{"appId":"B","time":6}
{"appId":"B","time":4}
{"appId":"B","time":2}
{"appId":"B","time":1}
{"appId":"A","time":5}
{"appId":"A","time":3}
{"appId":"A","time":1}
我试过这个查询:
collection.aggregate([{"$group":{"_id":{"a":"$appId"},"ttt":{"$max":"$time"}}},
{"$sort":{"_id.ttt":-1,"time":-1}}])
但我只收到了最后一次特定的 appId -> 2 结果,这个查询改变了数据的结构。我想保留文档的结构,并且只像示例一样对它们进行分组和排序。
解决方案
您可以尝试以下聚合:
db.collection.aggregate([
{
$sort: { time: -1 }
},
{
$group: {
_id: "$appId",
max: { $max: "$time" },
items: { $push: "$$ROOT" }
}
},
{
$sort: { max: -1 }
},
{
$unwind: "$items"
},
{
$replaceRoot: {
newRoot: "$items"
}
}
])
您可以在分组之前$sort以获得每个组内的正确顺序。然后,您可以在分组时使用特殊变量$$ROOT
来捕获整个 orinal 对象。在下一步中,您可以按$max
值排序并使用$unwind和$replaceRoot来取回相同数量的文档并将原始形状提升到根级别。