Đếm số lượng người dùng đến trước người dùng này theo thứ tự sắp xếp của bạn. Tôi sẽ bắt đầu với trường hợp đơn giản (sắp xếp không phức tạp) vì truy vấn trong trường hợp ghép phức tạp hơn, mặc dù ý tưởng hoàn toàn giống nhau.
> db.test.drop()
> for (var i = 0; i < 10; i++) db.test.insert({ "x" : i })
> db.test.find({ }, { "_id" : 0 }).sort({ "x" : -1 }).limit(5)
{ "x" : 9 }
{ "x" : 8 }
{ "x" : 7 }
{ "x" : 6 }
{ "x" : 5 }
Đối với thứ tự này, thứ hạng của tài liệu { "x" : i }
là số lượng tài liệu { "x" : j }
với i < j
> var rank = function(id) {
var i = db.test.findOne({ "_id" : id }).x
return db.test.count({ "x" : { "$gt" : i } })
}
> var id = db.test.findOne({ "x" : 5 }).id
> rank(id)
4
Xếp hạng sẽ dựa trên 0. Tương tự, nếu bạn muốn tính thứ hạng cho tài liệu { "x" : i }
theo kiểu { "x" : 1 }
, bạn sẽ đếm số tài liệu { "x" : j }
với i > j
.
Đối với sắp xếp phức hợp, quy trình tương tự hoạt động, nhưng khó triển khai hơn vì thứ tự trong chỉ mục kết hợp là từ vựng, tức là đối với sắp xếp { "a" : 1, "b" : 1}
, (a, b) < (c, d)
nếu a < c
hoặc a = c
và b < d
, vì vậy chúng tôi cần một truy vấn phức tạp hơn để thể hiện điều kiện này. Đây là một ví dụ cho một chỉ mục kết hợp:
> db.test.drop()
> for (var i = 0; i < 3; i++) {
for (var j = 0; j < 3; j++) {
db.test.insert({ "x" : i, "y" : j })
}
}
> db.test.find({}, { "_id" : 0 }).sort({ "x" : 1, "y" : -1 })
{ "x" : 0, "y" : 2 }
{ "x" : 0, "y" : 1 }
{ "x" : 0, "y" : 0 }
{ "x" : 1, "y" : 2 }
{ "x" : 1, "y" : 1 }
{ "x" : 1, "y" : 0 }
{ "x" : 2, "y" : 2 }
{ "x" : 2, "y" : 1 }
{ "x" : 2, "y" : 0 }
Để tìm thứ hạng cho tài liệu { "x" : i, "y" : j }
, bạn cần tìm số lượng tài liệu { "x" : a, "y" : b }
theo thứ tự { "x" : 1, "y" : -1 }
sao cho (i, j) < (a, b)
. Với đặc điểm kỹ thuật sắp xếp, điều này tương đương với điều kiện i < a
hoặc i = a
và j > b
:
> var rank = function(id) {
var doc = db.test.findOne(id)
var i = doc.x
var j = doc.y
return db.test.count({
"$or" : [
{ "x" : { "$lt" : i } },
{ "x" : i, "y" : { "$gt" : j } }
]
})
}
> id = db.test.findOne({ "x" : 1, "y" : 1 })._id
> rank(id)
4
Cuối cùng, trong trường hợp của bạn về chỉ số phức hợp ba phần
{ "score" : -1, "time" : 1, "bonus" : -1 }
rank
chức năng sẽ là
> var rank = function(id) {
var doc = db.test.findOne(id)
var score = doc.score
var time = doc.time
var bonus = doc.bonus
return db.test.count({
"$or" : [
{ "score" : { "$gt" : score } },
{ "score" : score, "time" : { "$lt" : time } },
{ "score" : score, "time" : time, "bonus" : { "$gt" : bonus } }
]
})
}