Andrey Yaskulsky
Andrey Yaskulsky

Reputation: 2516

Get average value from array consisting of objects based on objects fields

I have a document of the following structure:

{
    "_id" : ObjectId("598446bb13c7141f1"),
    "trackerId" : "598446ba-fa9b-4000-8000-4ea290e",
    "powerMetrics" : [ 
        {
            "duration" : 0.15,
            "powerConsumption" : 0.1
        }, 
        {
            "duration" : 0.1,
            "powerConsumption" : 0.05
        }
    ]
}

My goal is to get another document, which would contain a single value avgMetric. This avgMetrics should be calculated using powerMetrics array in the following way:

    (powerMetrics[0].powerConsumption/powerMetrics[0].duration 
  + powerMetrics[1].powerConsumption/powerMetrics[1].duration) /  powerMetrics.size()

So this avgMetrics should represent the average of all (powerConsumption/duration) from the powerMetrics array.

After experimenting with query I could not achieve this,

Size of the powerMetrics array can vary, Mongo db version is 3.2.14

Could someone please help with that?

Thanks

Upvotes: 1

Views: 89

Answers (2)

Rubin Porwal
Rubin Porwal

Reputation: 3845

db.collection.aggregate(

    // Pipeline
    [
        // Stage 1
        {
            $unwind: {
                path: "$powerMetrics",
                preserveNullAndEmptyArrays: true // optional
            }
        },

        // Stage 2
        {
            $group: {
                _id: '$_id',
                metrics: {
                    $addToSet: {
                        $divide: ['$powerMetrics.powerConsumption', '$powerMetrics.duration']
                    }
                }
            }
        },

        // Stage 3
        {
            $project: {
                avgVal: {
                    $avg: '$metrics'
                }
            }
        },

    ]



);

Upvotes: 0

s7vr
s7vr

Reputation: 75964

You can use $map to with $avg to output avg in 3.2 mongo version.

db.col_name.aggregate(
[{"$project":{
  "avgMetrics":{
    "$avg":{
      "$map":{
        "input":"$powerMetrics",
         "as":"val",
         "in":{"$divide":["$$val.powerConsumption","$$val.duration"]}
      }
    }
  }
}}])

Upvotes: 2

Related Questions