MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

Как да получите класиране на артикул в списък, сортиран по множество полета в Mongoose

Пребройте броя на потребителите, които идват преди този потребител във вашия ред на сортиране. Ще започна с случая на просто (несъставно сортиране), защото заявката в сложния случай е по-сложна, въпреки че идеята е абсолютно същата.

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

За тази поръчка, класирането на документ { "x" : i } е броят на документите { "x" : j } с 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

Класирането ще се базира на 0. По същия начин, ако искате да изчислите ранга за документа { "x" : i } в сортирането { "x" : 1 } , ще преброите броя на документите { "x" : j } с i > j .

За комбинирано сортиране същата процедура работи, но е по-трудно да се приложи, тъй като редът в съставния индекс е лексикографски, т.е. за сортирането { "a" : 1, "b" : 1} , (a, b) < (c, d) ако a < c или a = c и b < d , така че се нуждаем от по-сложна заявка, за да изразим това условие. Ето пример за съставен индекс:

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

За да намерите ранга на документа { "x" : i, "y" : j } , трябва да намерите броя на документите { "x" : a, "y" : b } в реда { "x" : 1, "y" : -1 } така че (i, j) < (a, b) . Като се има предвид спецификацията за сортиране, това е еквивалентно на условието i < a или i = a и 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

И накрая, във вашия случай на съставен индекс от три части

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

rank функция ще бъде

> 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. 3 начина за създаване на индекс в MongoDB

  2. Каква е разликата между операторите .in() и all.() в mongoose?

  3. Mongoose геопространствено търсене:разстоянието не работи

  4. SpringData Mongo @Column еквивалентна анотация (@Property?)

  5. Намерете използването на _id, което не работи с агрегиране