Вам не нужно использовать $reduce
. Просто $sum
может сделать работу.
db.collection.aggregate([
{ "$project": {
"result": {
"foo": { "$divide": [{ "$sum": "$results.foo" }, { "$size": "$results" }] },
"bar": { "$divide": [{ "$sum": "$results.bar" }, { "$size": "$results" }] }
}
}}
])
Обновление -> в соответствии с динамическими ключами внутри results
массив
db.collection.aggregate([
{ "$project": {
"aggDate": 1,
"results": {
"$reduce": {
"input": {
"$map": { "input": "$results", "in": { "$objectToArray": "$$this" }}
},
"initialValue": [],
"in": { "$concatArrays": ["$$value", "$$this"] }
}
}
}},
{ "$project": {
"aggDate": 1,
"result": {
"$arrayToObject": {
"$map": { "input": { "$setUnion": ["$results.k"] },
"as": "m",
"in": {
"$let": {
"vars": {
"fil": {
"$filter": {
"input": "$results",
"as": "d",
"cond": { "$eq": ["$$d.k", "$$m"] }
}
}
},
"in": {
"k": "$$m",
"v": { "$divide": [{ "$sum": "$$fil.v" }, { "$size": "$$fil" }] }
}
}
}
}
}
}
}}
])
MongoPlayground
С более упрощенной версией и с одной $project
ступенью
db.collection.aggregate([
{ "$project": {
"aggDate": 1,
"result": {
"$let": {
"vars": {
"red": {
"$reduce": {
"input": {
"$map": { "input": "$results", "in": { "$objectToArray": "$$this" }}
},
"initialValue": [],
"in": { "$concatArrays": ["$$value", "$$this"] }
}
}
},
"in": {
"$arrayToObject": {
"$map": { "input": { "$setUnion": ["$$red.k"] },
"as": "m",
"in": {
"$let": {
"vars": {
"fil": {
"$filter": {
"input": "$$red",
"as": "d",
"cond": { "$eq": ["$$d.k", "$$m"] }
}
}
},
"in": {
"k": "$$m",
"v": { "$divide": [{ "$sum": "$$fil.v" }, { "$size": "$$fil" }] }
}
}
}
}
}
}
}
}
}}
])
MongoPlayground
И оба выводятся как
[
{
"_id": ObjectId("5a934e000102030405000000"),
"aggDate": "2019-05-23",
"result": {
"bar": 0.7,
"foho": 0.32,
"foo": 0.58,
"sdbar": 0.98
}
}
]