sql >> Database teknologi >  >> NoSQL >> MongoDB

Sådan får du vareplacering i listen sorteret efter flere felter i Mongoose

Tæl antallet af brugere, der kommer før denne bruger i din sorteringsrækkefølge. Jeg starter med sagen om en simpel (ikke-sammensat sortering), fordi forespørgslen i den sammensatte sag er mere kompliceret, selvom ideen er nøjagtig den samme.

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

For denne rækkefølge, rangeringen af ​​et dokument { "x" : i } er antallet af dokumenter { "x" : j } med 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

Rangeringen vil være baseret på 0. På samme måde, hvis du ønsker at beregne rangeringen for dokumentet { "x" : i } i sorteringen { "x" : 1 } , ville du tælle antallet af dokumenter { "x" : j } med i > j .

For en sammensat sortering fungerer den samme procedure, men det er vanskeligere at implementere, fordi rækkefølgen i et sammensat indeks er leksikografisk, dvs. for sorteringen { "a" : 1, "b" : 1} , (a, b) < (c, d) hvis a < c eller a = c og b < d , så vi har brug for en mere kompliceret forespørgsel for at udtrykke denne betingelse. Her er et eksempel på et sammensat indeks:

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

For at finde rangeringen for dokumentet { "x" : i, "y" : j } , skal du finde antallet af dokumenter { "x" : a, "y" : b } i rækkefølgen { "x" : 1, "y" : -1 } sådan at (i, j) < (a, b) . Givet sorteringsspecifikationen svarer dette til betingelsen i < a eller i = a og 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

Til sidst, i dit tilfælde med et tredelt sammensat indeks

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

rank funktion ville være

> 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. Sådan kører du rå mongodb-kommandoer fra pymongo

  2. ScaleGrid annoncerer MongoDB Hosting Services i Canada

  3. Gå gennem Mongo Collection og opdater et felt i hvert dokument

  4. forstå nyt mongo-id og brug det med iron-router