sql >> Databáze >  >> NoSQL >> MongoDB

MongoDB:Aktualizace průměru v dokumentu se 2 vnořenými poli

Nemůžete použít aggregation k aktualizaci dokumentu, ale rozhodně jej můžete použít k získání dat, která chcete použít pro aktualizaci. Nejprve jsem si všiml, že existují nějaké {} chybí kolem vašeho grade objekt uvnitř grade pole. Možná budete chtít znovu zkontrolovat, zda struktura vašeho dokumentu odpovídá zaúčtování. Za druhé, existuje několik problémů s vaším agregačním dotazem.

  1. $avg operátor pracuje uvnitř $group klauzule, nikoli $project .
  2. Když použijete $avg , nemusíte používat $sum .
  3. Chcete vytvořit průměr trucks.grades.grade.grade_number , která ve skutečnosti obsahuje číselnou hodnotu známky. To znamená, že vám chybí grade mezi grades a grade_number .

Pokud tyto problémy vyřešíte, zobrazí se dotaz podobný následujícímu:

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

Pro váš vzorový dokument to vrátí:

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

Nyní můžete tyto informace použít k aktualizaci average_grade pole. Pokud používáte MongoDB verze 2.6 nebo vyšší, aggregate metoda vrátí kurzor. Tímto kurzorem můžete iterovat a podle toho aktualizovat dokumenty.

V tomto příkladu hledám dokumenty, které mají konkrétní truck_id v jejich trucks pole a pokračujte v aktualizaci average_grade s hodnotou vypočítanou agregačním dotazem. Můžete jej upravit tak, aby vyhovoval vašim potřebám. V kombinaci s agregačním dotazem vypadá kód takto.

// 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. Importujte soubory CSV z adresáře, abyste mohli nasadit databázi na Rails

  2. VAROVÁNÍ Chyba:Kód meteoru musí vždy běžet v rámci metody Fiber při volání na serveru

  3. Mongoose najít/aktualizovat dílčí dokument

  4. Připojte se ke dvěma sbírkám v MongoDB