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

配列フィールドの長さに基づいてドキュメントを並べ替える方法

    ここで意味しているように見えるのは、構文が示すように「長さ」と呼ばれる「プロパティ」ではなく、「answers」配列の「長さ」に基づいて結果を「ソート」したいということです。ちなみに、モデルは「参照」されているため、この構文は不可能です。つまり、このコレクションのドキュメントの配列フィールド内に存在するデータは ObjectIdだけです。 それらの参照ドキュメントの値。

    ただし、これは .aggregate()を使用して行うことができます。 メソッドと $ size 演算子:

    Question.aggregate(
        [
            { "$project": {
                "title": 1,
                "content": 1,
                "created": 1,
                "updated": 1,
                "author": 1,
                "answers": 1,
                "length": { "$size": "$answers" }
            }},
            { "$sort": { "length": -1 } },
            { "$limit": 5 }
        ],
        function(err,results) {
            // results in here
        }
    )
    

    集約パイプラインは段階的に機能します。まず、 $ project > 結果のフィールドには、 $ sizeを使用します 指定された配列の長さを返します。

    これで「長さ」のフィールドができたので、を使用して、ステージをたどります。 $ sort および $ limit これらは、集約パイプライン内の独自のステージとして適用されます。

    より良いアプローチは、ドキュメント内の「answers」配列の長さプロパティを常に維持することです。これにより、他の操作なしで簡単に並べ替えとクエリを実行できます。これを維持するのは、 $ inc $ pushとしての演算子 または $ pull 配列からのアイテム:

    Question.findByIdAndUpdate(id,
        {
            "$push": { "answers": answerId },
            "$inc": { "answerLength": 1 } 
        },
        function(err,doc) {
    
        }
    )
    

    または、削除する場合はその逆:

    Question.findByIdAndUpdate(id,
        {
            "$pull": { "answers": answerId },
            "$inc": { "answerLength": -1 } 
        },
        function(err,doc) {
    
        }
    )
    

    アトミック演算子を使用していない場合でも、「長さ」を更新するときに同じ原則が適用されます。次に、並べ替えを使用したクエリは簡単です:

    Question.find().sort({ "answerLength": -1 }).limit(5).exec(function(err,result) {
    
    });
    

    プロパティはすでにドキュメントにあるため。

    したがって、 .aggregate()を使用して実行します データを変更せずに、またはデータを変更して常に長さをプロパティとして含めると、クエリが非常に高速になります。



    1. Redisluaスクリプトが機能しない

    2. Spring Data Mongodb:ドキュメントの更新

    3. mgo $ unwind集計結果を不明な要素の種類(0x2E)に

    4. MongoJsonスキーマバリデーターAnyOfが機能していません