sql >> データベース >  >> NoSQL >> MongoDB

マングースの複数のフィールドでソートされたリストでアイテムのランキングを取得する方法

    ソート順でこのユーザーの前に来るユーザーの数を数えます。アイデアはまったく同じですが、複合の場合のクエリはより複雑であるため、単純な(複合ではないソート)場合から始めます。

    > 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 を使用

    > 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 の場合 またはa=c およびb したがって、この条件を表現するには、より複雑なクエリが必要です。複合インデックスの例を次に示します。

    > 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 と同等です。 または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
    

    最後に、3部構成の複合インデックスの場合

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

    ランク 関数は

    になります
    > 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. Laravelのredisパイプライン機能の外部で変数にアクセスする

    3. Azure上のMongoDB:適切なインスタンスタイプを選択する方法は?

    4. Mongoのupdate()関数内で$ addを使用するにはどうすればよいですか?