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

MongoDB:2つのネストされた配列を持つドキュメントの平均を更新する

    aggregationは使用できません ドキュメントを更新しますが、更新に使用するデータを取得するために間違いなく使用できます。まず、{}があることに気づきました gradeの周りにありません grades内のオブジェクト 配列。文書構造が転記されたとおりであることを再確認することをお勧めします。次に、集計クエリにはいくつかの問題があります。

    1. $avg 演算子は$group内で機能します $projectではなく句 。
    2. $avgを使用する場合 、$sumを使用する必要はありません 。
    3. 平均化するtrucks.grades.grade.grade_number 、実際にはグレードの数値を保持します。つまり、gradeがありません gradesの間 およびgrade_number

    これらの問題を解決すると、次のようなクエリが表示されます。

    db.col.aggregate([ 
        { "$unwind": "$trucks" }, 
        { "$unwind": "$trucks.grades" }, 
        { "$group":
            { 
                "_id": "$trucks.truck_id", 
                "average_grade": { "$avg": "$trucks.grades.grade_number" } 
            } 
        }
    ]);
    

    サンプルドキュメントの場合、次のようになります。

    { "_id" : "TEB5572", "average_grade" : 4 }
    { "_id" : "TEB7622", "average_grade" : 4 }
    

    これで、この情報を使用してaverage_gradeを更新できます。 分野。 MongoDBバージョン2.6以降を使用している場合は、aggregate メソッドはカーソルを返します。そのカーソルを繰り返し処理し、それに応じてドキュメントを更新できます。

    この例では、特定のtruck_idを持つドキュメントを検索します trucksの内部 配列を作成し、average_gradeの更新に進みます 集計クエリによって計算されたものを使用します。ニーズに合わせて変更できます。集計クエリと組み合わせると、コードは次のようになります。

    // Get average grade for each truck and assign results to cursor.
    var cur = db.col.aggregate([ 
        { "$unwind": "$trucks" }, 
        { "$unwind": "$trucks.grades" }, 
        { "$group":
            { 
                "_id": "$trucks.truck_id", 
                "average_grade": { "$avg": "$trucks.grades.grade_number" } 
            } 
        }
    ]);
    
    // Iterate through results and update average grade for each truck.
    while (cur.hasNext()) {
        var doc = cur.next();
        db.col.update({ "trucks.truck_id": doc._id },
                      { "$set": { "trucks.$.average_grade": doc.average_grade }},
                      { "multi": true});
    }
    



    1. Mongoidで日付でグループ化するための最良の方法

    2. MongoDb C#GeoNearクエリ構築

    3. mongooseを使用してMongoDBでfindAndModifyfuncの戻り値を取得する方法は?

    4. データベースからのJSONの保存とクエリ