sql >> Databasteknik >  >> NoSQL >> MongoDB

MongoDB:Uppdatering av ett genomsnitt i ett dokument med 2 kapslade arrayer

Du kan inte använda aggregation för att uppdatera ett dokument, men du kan definitivt använda det för att få de data du vill använda för en uppdatering. Först och främst märkte jag att det finns några {} saknas runt ditt grade objekt i grades array. Du kanske vill dubbelkolla att din dokumentstruktur är som den har lagts upp. För det andra finns det ett par problem med din aggregeringsfråga.

  1. $avg operatorn arbetar i en $group sats, inte ett $project .
  2. När du använder $avg , du behöver inte använda $sum .
  3. Du vill ha ett genomsnitt av trucks.grades.grade.grade_number , som faktiskt håller betygets numeriska värde. Det vill säga, du saknar grade mellan grade och grade_number .

Om du löser dessa problem får du en fråga som liknar följande:

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

För ditt exempeldokument returnerar det:

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

Nu kan du använda denna information för att uppdatera average_grade fält. Om du använder MongoDB version 2.6 eller högre, aggregate metod returnerar en markör. Du kan iterera genom den markören och uppdatera dokumenten därefter.

I det här exemplet söker jag efter dokument som har ett särskilt truck_id inuti sina trucks array och fortsätt med att uppdatera average_grade med den som beräknas av aggregeringsfrågan. Du kan modifiera den för att passa dina behov. I kombination med aggregeringsfrågan ser koden ut så här.

// 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. MongoDB-grupp med flera id

  2. Få alla nycklar i Redis-databasen med python

  3. Kan inte ta bort från mongodb-samlingens vinklade MEAN-stack

  4. mongodb flytta dokument från en samling till en annan samling