içinde birden çok alana göre sıralı sırada madde sıralaması almak için MongoDB koleksiyonunda bir dizi kullanıcı kaydına sahibim (> 10000), ancak desc + time asc + bonus desc. Mongoose kullanarak bu sıralamaya göre listedeki bir kullanıcının sıralamasını nasıl alabilirim? Dizin doğru bir şekilde oluşturulduğunu varsayalım.Mongoose
Mongoose
cevap
Bu kullanıcıdan önce gelen kullanıcı sayısını sıralama düzeninize göre sayın. Basit (bileşik olmayan bir sıralama) durum ile başlayacağım çünkü fikir tam olarak aynı olsa bile, bileşik vakadaki sorgu daha karmaşıktır. sizin için rütbe hesaplamak istiyorsanız bu sipariş için
> 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 }
, bir belgenin
{ "x" : i }
sıralamasında, Benzer sıralama 0'dan esas alınacaktır
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
ile belgelerin { "x" : j }
sayısıdır belgesindeki { "x" : 1 }
numaralı belgede, { "x" : j }
belgelerinin sayısını i > j
ile sayarsınız. Bir bileşik tür için
(a, b) < (c, d)
a < c
veya
a = c
ve
b < d
eğer sıralama
{ "a" : 1, "b" : 1}
için, yani uygulamak daha zordur, bu yüzden daha ihtiyacımız Bu durumu ifade etmek için karmaşık bir sorgu. İşte bileşik endeksi için bir örnek:
> 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 }
belgenin { "x" : i, "y" : j }
için rütbe bulmak için, sırayla { "x" : 1, "y" : -1 }
şekilde (i, j) < (a, b)
belge { "x" : a, "y" : b }
sayısını bulmalıyız. sıralama şartname göz önüne alındığında, bu durumun i < a
veya i = a
ve j > b
eşdeğerdir:
> 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
Son olarak, üç parçalı bileşik endeksi sizin durumunuzda
{ "score" : -1, "time" : 1, "bonus" : -1 }
rank
işlevi olacağını
> 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 } }
]
})
}