gpt4 book ai didi

mongodb - 根据关键值对文档进行排序和排名?

转载 作者:可可西里 更新时间:2023-11-01 09:24:04 25 4
gpt4 key购买 nike

我正在尝试为集合中的学生提取得分最高的文档,并在下面形成查询:

{ name: "Person1", marks: 20  }
{ name: "Person2", marks: 20 }
{ name: "Person1", marks: 30 }
{ name: "Person1", marks: 25 }
{ name: "Person2", marks: 50 }
{ name: "Person1", marks: 90 }
{ name: "Person3", marks: 990 }

我的查询:

db.mytest1.aggregate( [          
{ $sort : { "name" : 1,"marks" : -1} },
{$group:
{
_id: "$name",
name: { $first: "$name" },
marks: { $first: "$marks" }
}}
])

有更好的方法吗?

如果我的场景是根据标记对文档进行编号,我该如何实现?

我想得到以下结果:

{ name: "Person1", marks: 90,  rank: 1 }
{ name: "Person1", marks: 30, rank: 2 }
{ name: "Person1", marks: 25, rank: 3 }
{ name: "Person1", marks: 20, rank: 4 }
{ name: "Person2", marks: 50, rank: 1 }
{ name: "Person2", marks: 20, rank: 2 }
{ name: "Person3", marks: 990, rank: 3 }

最佳答案

我真的认为这是最实用的简单游标迭代,但稍后会详细介绍。

使用聚合框架进行“小型”分组的最快实用方法是使用 MongoDB 3.2 引入的 $unwind 中的 includeArrayIndex:

db.mytest1.aggregate([
{ "$sort": { "name" : 1,"marks" : -1} },
{ "$group": {
"_id": "$name",
"items": { "$push": "$$ROOT" }
}},
{ "$unwind": { "path": "$items", "includeArrayIndex": "items.rank" } },
{ "$replaceRoot": { "newRoot": "$items" } },
{ "$sort": { "name" : 1,"marks" : -1} }
])

产生:

{ "name" : "Person1", "marks" : 90, "rank" : NumberLong(0) }
{ "name" : "Person1", "marks" : 30, "rank" : NumberLong(1) }
{ "name" : "Person1", "marks" : 25, "rank" : NumberLong(2) }
{ "name" : "Person1", "marks" : 20, "rank" : NumberLong(3) }
{ "name" : "Person2", "marks" : 50, "rank" : NumberLong(0) }
{ "name" : "Person2", "marks" : 20, "rank" : NumberLong(1) }
{ "name" : "Person3", "marks" : 990, "rank" : NumberLong(0) }

或者走得更远一点:

db.mytest1.aggregate([
{ "$sort": { "name" : 1,"marks" : -1} },
{ "$group": {
"_id": "$name",
"items": { "$push": "$$ROOT" }
}},
{ "$unwind": { "path": "$items", "includeArrayIndex": "items.rank" } },
{ "$project": {
"_id": 0,
"name": "$items.name",
"marks": "$items.marks",
"rank": { "$add": [ "$items.rank", 1 ] }
}},
{ "$sort": { "name" : 1,"marks" : -1} }
])

以你想要的方式。

{ "name" : "Person1", "marks" : 90, "rank" : 1 }
{ "name" : "Person1", "marks" : 30, "rank" : 2 }
{ "name" : "Person1", "marks" : 25, "rank" : 3 }
{ "name" : "Person1", "marks" : 20, "rank" : 4 }
{ "name" : "Person2", "marks" : 50, "rank" : 1 }
{ "name" : "Person2", "marks" : 20, "rank" : 2 }
{ "name" : "Person3", "marks" : 990, "rank" : 1 }

但是要小心,因为我们将所有内容都放入一个数组中进行“分组”,以便在提取时获得“索引”位置。这适用于小型列表,但您永远不会尝试使用数千个项目。

对于 1000 项,然后迭代游标并在中断处排名:

var current = null,
rank = 0;

db.mytest1.find().sort({ "name": 1, "marks": -1 }).forEach(doc => {
if ( doc.name != current || current == null ) {
rank = 0;
current = doc.name;
}
rank++;
doc.rank = rank;
delete doc._id;
printjson(doc);
})

这是相同的结果:

{ "name" : "Person1", "marks" : 90, "rank" : 1 }
{ "name" : "Person1", "marks" : 30, "rank" : 2 }
{ "name" : "Person1", "marks" : 25, "rank" : 3 }
{ "name" : "Person1", "marks" : 20, "rank" : 4 }
{ "name" : "Person2", "marks" : 50, "rank" : 1 }
{ "name" : "Person2", "marks" : 20, "rank" : 2 }
{ "name" : "Person3", "marks" : 990, "rank" : 1 }

实际上,您也可以这样做,因为它既简单又快速。

关于mongodb - 根据关键值对文档进行排序和排名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44587829/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com