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

Vypočítejte průměr polí ve vložených dokumentech/pole

Agregační rámec v MongoDB 3.4 a novějších nabízí $reduce operátor, který efektivně vypočítá součet bez potřeby dalších potrubí. Zvažte jeho použití jako výraz pro vrácení celkového hodnocení a získání počtu hodnocení pomocí $size . Společně s $addFields , průměr lze tedy vypočítat pomocí aritmetického operátoru $divide jako ve vzorci average = total ratings/number of ratings :

db.collection.aggregate([
    { 
        "$addFields": { 
            "rating_average": {
                "$divide": [
                    { // expression returns total
                        "$reduce": {
                            "input": "$ratings",
                            "initialValue": 0,
                            "in": { "$add": ["$$value", "$$this.rating"] }
                        }
                    },
                    { // expression returns ratings count
                        "$cond": [
                            { "$ne": [ { "$size": "$ratings" }, 0 ] },
                            { "$size": "$ratings" }, 
                            1
                        ]
                    }
                ]
            }
        }
    }           
])

Ukázkový výstup

{
    "_id" : ObjectId("58ab48556da32ab5198623f4"),
    "title" : "The Hobbit",
    "ratings" : [ 
        {
            "title" : "best book ever",
            "rating" : 5.0
        }, 
        {
            "title" : "good book",
            "rating" : 3.5
        }
    ],
    "rating_average" : 4.25
}

U starších verzí byste museli nejprve použít $unwind operátor na ratings pole pole jako první krok agregačního kanálu. Tím se dekonstruují ratings pole ze vstupních dokumentů pro výstup dokumentu pro každý prvek. Každý výstupní dokument nahradí pole hodnotou prvku.

Druhá fáze kanálu by byla $group operátor, který seskupuje vstupní dokumenty podle _id a title klíčový výraz identifikátoru a použije požadovaný $avg akumulátorový výraz ke každé skupině, která počítá průměr. Existuje další operátor akumulátoru $push který zachová původní pole pole hodnocení tím, že vrátí pole všech hodnot, které jsou výsledkem použití výrazu na každý dokument ve výše uvedené skupině.

Posledním krokem v kanálu je $project operátor, který poté změní tvar každého dokumentu ve streamu, například přidáním nového pole ratings_average .

Pokud tedy například máte ve sbírce vzorový dokument (jak shora, tak níže):

db.collection.insert({
    "title": "The Hobbit",

    "ratings": [
        {
            "title": "best book ever",
            "rating": 5
        },
        {
            "title": "good book",
            "rating": 3.5
        }
    ]
})

Pro výpočet průměru pole hodnocení a promítnutí hodnoty do jiného pole ratings_average , pak můžete použít následující agregační kanál:

db.collection.aggregate([
    {
        "$unwind": "$ratings"
    },
    {
        "$group": {
            "_id": {
                "_id": "$_id",
                "title": "$title"
            },
            "ratings":{
                "$push": "$ratings"
            },
            "ratings_average": {
                "$avg": "$ratings.rating"
            }
        }
    },
    {
        "$project": {
            "_id": 0,
            "title": "$_id.title",
            "ratings_average": 1,
            "ratings": 1
        }
    }
])

Výsledek :

/* 1 */
{
    "result" : [ 
        {
            "ratings" : [ 
                {
                    "title" : "best book ever",
                    "rating" : 5
                }, 
                {
                    "title" : "good book",
                    "rating" : 3.5
                }
            ],
            "ratings_average" : 4.25,
            "title" : "The Hobbit"
        }
    ],
    "ok" : 1
}


  1. Připojení k MongoDB Atlas pomocí Golang mgo:Trvalý nedostupný server pro sadu replik

  2. Konverze slovníku<řetězec, objekt>-na-BsonDocument s vynecháním pole _t

  3. Výkon HBase CDH5 (HBase1) vs CDH6 (HBase2)

  4. Platnost Mongoose vyprší majetek, který nefunguje správně