sql >> Database >  >> NoSQL >> MongoDB

Hoe u de itemrangschikking in de lijst kunt krijgen, gesorteerd op meerdere velden in Mongoose

Tel het aantal gebruikers dat voor deze gebruiker komt in uw sorteervolgorde. Ik begin met het geval van een eenvoudige (niet-samengestelde sortering) omdat de query in het samengestelde geval ingewikkelder is, ook al is het idee precies hetzelfde.

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

Voor deze volgorde, de rangorde van een document { "x" : i } is het aantal documenten { "x" : j } met 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

De rangorde wordt gebaseerd op 0. Evenzo, als u de rangorde voor het document { "x" : i } wilt berekenen in de sortering { "x" : 1 } , zou u het aantal documenten tellen { "x" : j } met i > j .

Voor een samengestelde sortering werkt dezelfde procedure, maar het is lastiger te implementeren omdat de volgorde in een samengestelde index lexicografisch is, d.w.z. voor de sortering { "a" : 1, "b" : 1} , (a, b) < (c, d) als a < c of a = c en b < d , dus we hebben een meer gecompliceerde query nodig om deze voorwaarde uit te drukken. Hier is een voorbeeld voor een samengestelde index:

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

Om de rang voor het document te vinden { "x" : i, "y" : j } , moet u het aantal documenten vinden { "x" : a, "y" : b } in de volgorde { "x" : 1, "y" : -1 } zodanig dat (i, j) < (a, b) . Gezien de sorteerspecificatie komt dit overeen met de voorwaarde i < a of i = a en 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

Tot slot, in uw geval van een driedelige samengestelde index

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

de rank functie zou zijn

> 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. Mongoose:hoe aggregaat gebruiken en samen zoeken

  2. 5 manieren om de minuten van een date in MongoDB te krijgen

  3. Hoe SQLdecode-fout op te lossen wanneer u modellen in django migreert?

  4. Hoe u de itemrangschikking in de lijst kunt krijgen, gesorteerd op meerdere velden in Mongoose