MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

Jak uzyskać ranking przedmiotów na liście posortowanej według wielu pól w Mongoose?

Policz liczbę użytkowników poprzedzających tego użytkownika w kolejności sortowania. Zacznę od przypadku prostego (niezłożonego sortowania), ponieważ zapytanie w przypadku złożonym jest bardziej skomplikowane, mimo że idea jest dokładnie taka 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 }

W tym porządku ranking dokumentu { "x" : i } to liczba dokumentów { "x" : j } z 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

Ranking będzie oparty na 0. Podobnie, jeśli chcesz obliczyć rangę dla dokumentu { "x" : i } w sortowaniu { "x" : 1 } , powinieneś policzyć liczbę dokumentów { "x" : j } z i > j .

W przypadku sortowania złożonego działa ta sama procedura, ale jest trudniejsza do zaimplementowania, ponieważ kolejność w indeksie złożonym jest leksykograficzna, tj. dla sortowania { "a" : 1, "b" : 1} , (a, b) < (c, d) jeśli a < c lub a = c i b < d , więc do wyrażenia tego warunku potrzebujemy bardziej skomplikowanego zapytania. Oto przykład indeksu złożonego:

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

Aby znaleźć rangę dokumentu { "x" : i, "y" : j } , musisz znaleźć liczbę dokumentów { "x" : a, "y" : b } w kolejności { "x" : 1, "y" : -1 } tak, że (i, j) < (a, b) . Biorąc pod uwagę specyfikację sortowania, jest to równoważne warunku i < a lub i = a i 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

Wreszcie, w twoim przypadku trzyczęściowego indeksu złożonego

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

rank funkcja byłaby

> 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. Spark nie wykonuje zadań

  2. Jak mogę użyć mongodump do zrzucenia rekordów pasujących do określonego zakresu dat?

  3. findAndModify lub findOneAndUpdate - nie jest funkcją

  4. MongoDB -- duża liczba baz danych

  5. MongoError:nie udało się połączyć z serwerem przy pierwszym połączeniu