我正在使用 MongoDB 创建一个排行榜系统,所以,我想知道我是否有可能获得列表中文档及其邻居的位置。
{ "_id": null, "name": "user_341c88077d", "value": 140 },
{ "_id": null, "name": "user_6fd772cb84", "value": 160 },
{ "_id": null, "name": "user_73bdbb334f", "value": 180 },
{ "_id": null, "name": "user_e16345075c", "value": 170 },
{ "_id": null, "name": "user_5902274617", "value": 220 }
我有一个与此类似的列表,我的目标是在尝试查找 {'name': "user_73bdbb334f"}
时获得与此类似的结果
{ "position": 3, "_id": null, "name": "user_e16345075c", "value": 170 },
{ "position": 4, "_id": null, "name": "user_73bdbb334f", "value": 180 },
{ "position": 5, "_id": null, "name": "user_5902274617", "value": 220 }
是否可以用 MongoDB 做这样的事情?
最佳答案
您无法直接从 MongoDB 获取使用 position
枚举的文档。因此,您的手动工作要做。第二个问题是让邻居。如果你事先知道所需文档的位置,比如 i
,你可以只执行 .skip(i - 1).limit(3)
,并且会得到你的文件在中间的邻居。知道文档位置的唯一方法是对光标进行排序,然后计算出现在所需文档之前的文档数,这可以使用 .count()
来实现。但是您的问题是,多个用户可能具有相同的分数,因此您无法确定哪个相同分数的文档是必需的。
在这种情况下,唯一的方法是:
- 获取所需用户的分数,比如
user_score
- 然后获取具有
{score: {$lt: user_score}}
的文档数,例如less_count
- 然后获取具有
{score: user_score, name: {$lt: "user_xxx"}}
的文档数,比如eq_count
- 然后累加
total = less_count + eq_count + 1
,1
给邻居 - 然后获取{score: {$lte: user_score}, name: {$lte: "user_xxx"}}文档,按{score: 1, name: 1}排序,然后
.skip(total -1).limit(3)
但这总共有 4 个查询,我认为您最好使用手动方法。
下面是我为您的目标建议的 JavaScript 方式片段:
range = 1; # The range of neighbours to show from each side
currentIndex = 1;
meIndex = -1; # The position of the required username
db.pos.find()
.sort({value: 1})
.map(function(doc) {
doc.position = currentIndex;
if (doc._id == username) {
meIndex = currentIndex
}
currentIndex++;
return doc;
}
)
.filter(function(el, i, arr) {
return (meIndex != -1 && Math.abs(meIndex - el.position) <= range)
}
)
首先你枚举你的文档,同时找到需要的文档,然后过滤掉只留下需要的文档和它的邻居。
更新
顺便说一句,您不能将null
作为所有文档的_id
值,因为它是一个唯一索引。
关于mongodb - 我如何订购列表并在 MongoDB 上为其项目添加位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30431056/