Расчет процента внутри группы в конвейере агрегирования mongodb - PullRequest
1 голос
/ 11 апреля 2020

Рассчитать процент внутри группы в mongodb, используя конвейер агрегации. Предположим, у меня есть коллекция, как показано ниже, с некоторыми документами.

 [{
 "Name":"xyz" ,
 "Area":"London",
 "Sex":"Male"
 },
 {
"Name":"aaa" ,
 "Area":"London",
 "Sex":"Female"
},

{
"Name":"bbb" ,
 "Area":"London",
 "Sex":"Female"
},
{
"Name":"ccc" ,
 "Area":"London",
 "Sex":"Female"
},
 {
"Name":"abc" ,
 "Area":"Chile",
 "Sex":"Female"
},
 {
"Name":"xxx" ,
 "Area":"Chile",
 "Sex":"Male"
}

]

Я хочу, чтобы процентное соотношение мужчин и женщин по каждой области. Ожидаемый результат должен быть примерно таким.

 [
        {
            _id {
                area : 'London', Sex:'Male'
            },

            percentage: 25
        },
       {
            _id {
                area : 'London', Sex:'Female'
            },

            percentage: 75
        },

        {
            _id {
                area : 'Chile', Sex:'Female'
            },

            percentage: 50
        },
         {
            _id {
                area : 'Chile', Sex:'Male'
            },

            percentage: 50
        }

]

1 Ответ

1 голос
/ 11 апреля 2020

Нам нужно сгруппировать по Area + Sex, чтобы вычислить общую стоимость. Затем мы снова группируем только по area и вычисляем процент.

Попробуйте это:

db.collection.aggregate([
  {
    $group: {
      _id: {
        area: "$Area",
        Sex: "$Sex"
      },
      total: {
        $sum: 1
      }
    }
  },
  {
    $group: {
      _id: "$_id.area",
      area: {
        $push: "$$ROOT"
      },
      total: {
        $sum: "$total"
      }
    }
  },
  {
    $addFields: {
      area: {
        $map: {
          input: "$area",
          in: {
            _id: "$$this._id",
            percentage: {
              $multiply: [
                {
                  $divide: [ "$$this.total", "$total" ]
                },
                100
              ]
            }
          }
        }
      }
    }
  },
  {
    $unwind: "$area"
  },
  {
    $replaceRoot: {
      newRoot: "$area"
    }
  }
])

MongoPlayground

...