Group and Sum according to the position percentage MongoDb Aggregation

陌路散爱 提交于 2019-12-23 05:23:05

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!