use*_*890 5 sorting max mongodb aggregation-framework
这是我的 mongo 收藏“销售”:
{"title":"Foo", "hash": 17, "num_sold": 49,
"place": "ABC"}
{"title":"Bar", "hash": 18, "num_sold": 55,
"place": "CDF"}
{"title":"Baz", "hash": 17, "num_sold": 55,
"place": "JKN"}
{"title":"Spam", "hash": 17, "num_sold": 20,
"place": "ZSD"}
{"title":"Eggs", "hash": 18, "num_sold": 20,
"place": "ZDF"}
Run Code Online (Sandbox Code Playgroud)
我想按哈希分组并返回具有最大“num_sold”的文档。所以作为输出我想看到:
{"title":"Baz", "hash": 17, "num_sold": 55,
"place": "JKN"}
{"title":"Bar", "hash": 18, "num_sold": 55,
"place": "CDF"}
Run Code Online (Sandbox Code Playgroud)
我知道聚合运算符的基础知识,这是我如何分组并获取 num_sold 最大值的方法,但我需要与最大值相对应的整个文档,而不仅仅是值。
db.getCollection('sales').aggregate([
{$group: {_id: "$hash", max_sold : {$max: '$value'}}}
])
Run Code Online (Sandbox Code Playgroud)
在 SQL 中我会用 join 来完成,但在 mongo 中。我还读到,在 mongo 中,组和排序不能很好地协同工作。
您可以使用$redact舞台来完成此任务。它避免了使用$sort然后再次执行 a$group或 an $unwind。
$groupby_id并获取每个组的最大值max_num_sold,使用运算符累加该组中的所有文档$push。$redact到每组的子文档中,只保留那些max_num_sold在其组中具有最大值的文档num_sold示例代码:
db.getCollection('sales').aggregate([
{$group:{"_id":"$hash",
"max_num_sold":{$max:"$num_sold"},
"records":{$push:"$$ROOT"}}},
{$redact:{$cond:[{$eq:[{$ifNull:["$num_sold","$$ROOT.max_num_sold"]},
"$$ROOT.max_num_sold"]},
"$$DESCEND","$$PRUNE"]}},
])
Run Code Online (Sandbox Code Playgroud)
测试数据:
db.getCollection('sales').insert([
{"title":"Foo","hash":17,"num_sold":49,"place":"ABC"},
{"title":"Bar","hash":18,"num_sold":55,"place":"CDF"},
{"title":"Baz","hash":17,"num_sold":55,"place":"JKN"},
{"title":"Spam","hash":17,"num_sold":20,"place":"ZSD"},
{"title":"Eggs","hash":18,"num_sold":20,"place":"ZDF"}
])
Run Code Online (Sandbox Code Playgroud)
测试结果:
{
"_id" : 18,
"max_num_sold" : 55,
"records" : [
{
"_id" : ObjectId("567874f2b506fc2193a22696"),
"title" : "Bar",
"hash" : 18,
"num_sold" : 55,
"place" : "CDF"
}
]
}
{
"_id" : 17,
"max_num_sold" : 55,
"records" : [
{
"_id" : ObjectId("567874f2b506fc2193a22697"),
"title" : "Baz",
"hash" : 17,
"num_sold" : 55,
"place" : "JKN"
}
]
}
Run Code Online (Sandbox Code Playgroud)