2015-04-14 5 views
7

У меня есть два документа, как этотMongoDB агрегация массив

{ "_id" : ObjectId("552cd26276b783ed66031cc4"), "vals" : [ 2, 3, 4, 5 ] } 
{ "_id" : ObjectId("552cd26e76b783ed66031cc5"), "vals" : [ 1, 2, 3, 4 ] } 

мне нужно агрегированный сумму этих двух списков

ожидается выход:

[3, 5, 7, 9] 

т.е. [2 + 1, 3 + 2 , 4 + 3, 5 + 4]

Я даже не уверен, возможно ли это в MongoDB. Какой-нибудь свет?

+0

Ваш массив 'vals' одинакового размера всегда? – Yogesh

+0

@yogesh No. Но я хотел бы знать, можно ли решить, если размер такой же. – thavan

+0

Я думаю, что это невозможно с помощью запроса манго. И +1 с моей стороны. – Yogesh

ответ

0

Извините, я не ответил на вопрос правильно. Я думал о том, как суммировать массив каждого объекта. Не добавлять массивы между двумя объектами.

(редактирование выше)

Я новичок в этом, но я думаю, что вы хотите использовать совокупный оператор $ раскрутку, который взорвется массив затем $ просуммировать «Vals». Он должен выглядеть как этот

db.Test.aggregate([{$unwind:"$vals"},{$group:{_id:"$_id","TotalVals":{$sum:"$vals"}}}]) 

относятся к операторам здесь http://docs.mongodb.org/manual/reference/operator/aggregation-group/

Это ($ размотки) создаст один документ для каждого значения в массиве таким образом наблюдать память для больших коллекций. Это ($ unwind) выполняется в памяти, я полагаю.

0

Структура агрегации - это не только конвейер агрегации.

Конечно, вы можете также использовать карту сократить с очень простыми функциями:

var map_function = function(){ 
    for(var i=0;i<this.vals.length;i++){ 
     emit(i,this.vals[i]); 
    } 
} 
var reduce_function = function(key, values){ 
    return Array.sum(values) 
} 

Выходной список документов, где _id является индексом и value является суммой. Пример:

[{u'_id': 0.0, u'value': 3.0}, 
{u'_id': 1.0, u'value': 5.0}, 
{u'_id': 2.0, u'value': 7.0}, 
{u'_id': 3.0, u'value': 9.0}] 
1

Просто для обновления. Это возможно в структуре агрегации в предстоящем выпуске mongoDB 3.2. Они добавили новую функцию, чтобы получить индекс разматывания массива в $ unwind этапе агрегации mongoDB под названием includeArrayIndex.

С помощью этой функции вы можете использовать совокупный запрос вида:

db.collection.aggregate(
    {$unwind: { path: "$vals", includeArrayIndex: "arrayIndex" }}, 
    {$group: { '_id': '$arrayIndex', sum : {$sum: '$vals'}}}, 
    {$sort: { '_id': 1 }}, 
    {$group : { '_id': null, valSum: {$push: '$sum'}}} 
) 

Объяснение:

  • разматывать операция разматывает массив Vals, а также проекты индекс массива размотки. Таким образом, идея состоит в том, чтобы группировать аналогичные индексы, чтобы мы могли их суммировать.
  • Затем мы группируем на основе arrayIndex, суммируя элемент vals.На этом этапе мы прекрасно суммируется соответствующие индексные элементы
  • Далее мы сортируем на основе arrayIndex таким образом, чтобы подготовить для окончательного результирующего массива
  • Далее группы все документы и раздвинуть суммы в массив под названием valSum

Выход:

{ '_id': null, valSum: [3, 5, 7, 9] } 

Основное преимущество такого подхода заключается в том, что вам не нужно иметь массивы одинаковой длины. Также он может принимать любое количество входных документов. Благодаря функции includeArrayIndex.

Cheers!

Смежные вопросы