MongoDB
 sql >> Teknologi Basis Data >  >> NoSQL >> MongoDB

Cara mendapatkan peringkat item dalam daftar yang diurutkan berdasarkan beberapa bidang di Mongoose

Hitung jumlah pengguna yang datang sebelum pengguna ini dalam urutan pengurutan Anda. Saya akan mulai dengan kasus sederhana (non-compound sort) karena kueri dalam kasus majemuk lebih rumit, meskipun idenya persis sama.

> 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 }

Untuk urutan ini, peringkat dokumen { "x" : i } adalah jumlah dokumen { "x" : j } dengan 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

Pemeringkatan akan didasarkan pada 0. Demikian pula, jika Anda ingin menghitung peringkat untuk dokumen { "x" : i } di sort { "x" : 1 } , Anda akan menghitung jumlah dokumen { "x" : j } dengan i > j .

Untuk pengurutan majemuk, prosedur yang sama bekerja, tetapi lebih sulit untuk diterapkan karena urutan dalam indeks majemuk adalah leksikografis, yaitu untuk pengurutan { "a" : 1, "b" : 1} , (a, b) < (c, d) jika a < c atau a = c dan b < d , jadi kita membutuhkan query yang lebih rumit untuk mengekspresikan kondisi ini. Berikut ini contoh untuk indeks gabungan:

> 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 }

Untuk mencari peringkat dokumen { "x" : i, "y" : j } , Anda perlu menemukan jumlah dokumen { "x" : a, "y" : b } dalam urutan { "x" : 1, "y" : -1 } sedemikian rupa sehingga (i, j) < (a, b) . Mengingat spesifikasi pengurutan, ini setara dengan kondisi i < a atau i = a dan 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

Terakhir, dalam kasus Anda tentang indeks gabungan tiga bagian

{ "score" : -1, "time" : 1, "bonus" : -1 }

rank fungsinya adalah

> 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 } }
        ]
    })
}



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Poligon kueri $geowithin $box mongodb tidak mengembalikan apa pun

  2. Tidak dapat terhubung ke mongodb

  3. Mencoba melakukan upsert massal dengan Mongoose. Apa cara terbersih untuk melakukan ini?

  4. Di mana saya harus meletakkan timeline aktivitas di mongodb, disematkan di pengguna atau secara terpisah?

  5. MongoDB - bagaimana cara menanyakan item bersarang di dalam koleksi?