Поэлементное суммирование массивов - PullRequest
1 голос
/ 17 апреля 2019

Рассмотрим этот набор документов:

[
  {_id:1, values:[1, 2, 3]},
  {_id:2, values:[4, 5, 6]}
]

Есть ли какой-нибудь элегантный способ группировки / суммирования массивов в новый массив, где n-й элемент - это сумма n-х элементов оригинальных документов?

{_id:null, values:[5, 7, 9]}

Я могу суммировать конкретные элементы на этапе агрегации:

{$group:{
    _id:null,
    Values0: {$sum:{$arrayElemAt:["$values",0]}},
    Values1: {$sum:{$arrayElemAt:["$values",1]}},
    Values2: {$sum:{$arrayElemAt:["$values",2]}}
}},

Но я не могу вернуть их обратно в массив.Также будет высоко цениться то, что потребует меньше печатать :).Если это не сработает, я могу перебрать документы bson в C # и построить ответ таким образом, но предпочел бы что-то в конвейере агрегации (или, может быть, mapreduce? Еще не рассматривал это)

1 Ответ

1 голос
/ 17 апреля 2019

Вы можете использовать $ group , чтобы получить массив массивов, а затем использовать $ reduce , чтобы обработать этот массив.Используя $ range , вы можете создавать индексы, которые можно использовать для получения каждого элемента обоих массивов (результат и текущий обрабатываемый элемент).Значение в индексе ноль будет initialValue для $reduce, а значения в индексах 1...size будут добавляться к результату на каждой итерации.

db.collection.aggregate([
    {
        $group: {
            _id: null,
            values : {
                $push: "$values"
            }
        }
    },
    {
        $project: {
            result: {
                $reduce: {
                    input: { $slice: [ "$values", 1, { $size: "$values" } ] },
                    initialValue: { $arrayElemAt: [ "$values", 0 ] },
                    in: {
                        $map: {
                            input: { $range: [ 0, { $size: "$$this" } ] },
                            as: "index",
                            in: {
                                $add: [
                                    { $arrayElemAt: [ "$$this", "$$index" ]  },
                                    { $arrayElemAt: [ "$$value", "$$index" ]  }
                                ]
                            }
                        }
                    }
                }
            }
        }
    }
])

Mongo Playground

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...