我有一個非常大的用戶串列(以百萬計)存盤在資料庫(在我們的例子中是 Mongo)中。每個用戶都有一個與之相關的分數。分數根據用戶的動作不斷變化。
當串列按分數排序時,我希望能夠查詢每個用戶的位置。
現在,我有一個分數索引。我查詢所有用戶,按分數對他們進行排序,然后遍歷以找到我想要的用戶的位置。
var users = User.find({})
.sort({
score: -1
});
var position = 1;
for (
let user = await users.next(); user !== null; user = await users.next()
) {
if (user === targetUser) {
return position;
}
position ;
}
排序是一個緩慢的操作,但根據我的理解,索引已經對它進行了排序,因此這與獲取所有記錄一樣昂貴。
由于串列已排序,我可以通過實作二進制搜索來提高查找元素的速度。
更大的問題是將串列存盤在記憶體中(我一直在 Node 中遇到堆記憶體不足的錯誤)。
什么是正確的資料庫 資料結構來實作我想要的?
uj5u.com熱心網友回復:
@barrypicker 我試過這個,它稍微快一點,但仍然很慢(大約 20 秒)。但我認為它可以解決我的記憶問題嗎?
// Get target user
let target = await User.findOne({
_id: targetId
});
// Find number of users with lower score without bringing all of them into memory
let lowerScoreCount = await User.count({
score: { $lt: target.score }
});
// Find all users with same score
let sameScoreSignups = await User.findOne({
score: target.score
});
// Iterate over users with same score till you find your user and add this to the lower score count to get the position of the user in the sorted list
let position = lowerScoreCount;
sameScoreSignups.forEach((user) => {
if (user._id === targetId) {
return position;
}
position ;
});
return position;
uj5u.com熱心網友回復:
您可以從 MongoDB v5.0 開始利用$setWindowFields并$rank可用。
db.collection.aggregate([
{
"$setWindowFields": {
"partitionBy": null,
"sortBy": {
"score": -1
},
"output": {
"rank": {
$rank: {}
}
}
}
},
{
$match: {
_id: <target user's identifier>
}
}
])
這是Mongo 游樂場供您參考。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/392581.html
標籤:数据库 MongoDB 排序 mongodb-查询
上一篇:嘗試制作重定向頁面
