问题
I have to group by the values of myArray and sum the total with a different attribution, it's mean for example for this documents we should make a distribution to make 40% of total for the the first value of the array and 40%(2/5) of total for the last and 20%(1/5) for others shared equitaly :
/* 1 */
{
"_id" : ObjectId("5a535c48a4d86ed94a7e8618"),
"total" : 5.8,
"myArray" : [
{
"value" : "a" 2/5 (40%)
},
{
"value" : "b 1/20 (20% /4)
},
{
"value" : "a" 1/20 (20% / 4)
},
{
"value" : "c" 1/20 (20% / 4)
},
{
"value" : "a" 1/20 (20% / 4)
},
{
"value" : "a" 2/5 (40%)
}
]
}
/* 2 */
{
"_id" : ObjectId("5a535c48a4d86ed94a7e8619"),
"total" : 4.5,
"myArray" : [
{
"value" : "a" 2/5 (40%)
},
{
"value" : c" 1/5 (20%)
},
{
"value" : "c" 2/5 (40%)
}
]
}
in this example we have to get :
"a" -> 2/5 * 5.8 + 2/5 * 5.8 + 1/10*5.8 + 1/10*5.8 2/5 * 4.5 / "b" -> 1/20*5.8 +0*4.5 / "c" -> 1/20*5.8 + 1/5*4.5 + 2/5*4.5
The result have to be like this :
[
{
"_id": "a",
"total": 2/5 * 5.8 + 2/5 * 5.8 + 1/10*5.8 + 1/10*5.8 2/5 * 4.5
},
{
"_id": "b",
"total": 1/20*5.8
},
{
"_id": "c",
"linear_total": 1/20*5.8 + 1/5*4.5 + 2/5*4.5
}
]
I have to group by Path.value and sum the correspondant values in each array with this logic
Thank you so much for the help
回答1:
You can try below aggregation in 3.4 pipeline.
Assign weights based on element position.
$switch
case to provide different weights based on size of array.
db.col.aggregate([{"$addFields":{
"myArray":{
"$switch":{
"branches":[{
"case":{"$gt":[{"$size":"$myArray"},2]},
"then":{"$concatArrays":[
[{"value":{"$arrayElemAt":["$myArray.value",0]},"weight":{"$divide":[2,5]}}],
{"$map":{
"input":{"$slice":["$myArray",1,{"$subtract":[{"$size":"$myArray"},2]}]},
"as":"val",
"in":{"value":"$$val.value","weight":{"$divide": [{"$divide":[1,5]},{"$subtract":[{"$size":"$myArray"},2]} ]}}
}},
[{"value":{"$arrayElemAt":["$myArray.value",-1]},"weight":{"$divide":[2,5]}}]
]}
},
{
"case":{"$eq":[{"$size":"$myArray"},2]},
"then":{"$concatArrays":[
[{"value":{"$arrayElemAt":["$myArray.value",0]},"weight":{"$divide":[1,2]}}],
[{"value":{"$arrayElemAt":["$myArray.value",-1]},"weight":{"$divide":[1,2]}}]
]}
}],
"default":{"$concatArrays":[
[{"value":{"$arrayElemAt":["$myArray.value",0]},"weight":1}],
]}}
}
}},
{"$unwind":"$myArray"},
{"$group":{
"_id":"$myArray.value",
"linear_total":{"$sum":{"$multiply":["$myArray.weight","$total"]}}
}},
{"$sort":{"_id":1}}])
来源:https://stackoverflow.com/questions/48167667/group-and-sum-according-to-the-position-percentage-mongodb-aggregation