2013-04-26 2 views
0

У меня есть документы, которые выглядят следующим образом:Можно ли использовать агрегатные функции с переменной в имени поля?

{ 
    (...stuff...) 
    something: { 
     first: { 
      0: 3, 
      1: 5, 
      2: 2 
     }, 
     second: { 
      0: 1, 
      1: 9, 
      2: 7 
     } 
    } 
} 

Для простоты в этом вопросе, я буду считать, что моя $match поражает только этот один документ. То, что я хотел бы сделать это, в общей команде, сложить 0 с, и складываем 1 с, и сложить 2 с, так что я могу производить что-то вроде этого:

something.0: 4 (something.first.0 + something.second.0) 
something.1: 14 (something.first.1 + something.second.1) 
something.2: 9 (something.first.2 + something.second.2) 

Является ли это чем-то, что можно сделать, или мне нужно изменить схему документа, чтобы изменить вложенные документы таким образом, чтобы все 0 s были вместе и т. Д.?

ответ

0

Если вы знаете имена всех массивов, которые вы хотите суммировать, вы можете использовать Aggregation Framework в MongoDB 2.2+ и проекцию с $add operator:

db.something.aggregate(
    { $project: { 
     something: { 
      0: { $add: [ "$something.first.0", "$something.second.0" ] }, 
      1: { $add: [ "$something.first.1", "$something.second.1" ] }, 
      2: { $add: [ "$something.first.2", "$something.second.2" ] } 
     } 
    }} 
) 

Пример вывода:

{ 
    "result" : [ 
     { 
      "_id" : ObjectId("517ae4914bc9ade96ca6402d"), 
      "something" : { 
       "0" : 4, 
       "1" : 14, 
       "2" : 9 
      } 
     } 
    ], 
    "ok" : 1 
} 

Если вы не знаете имена (т. Е. Используете попытку добавить 0-й элемент каждого элемента массива в документе), вам нужно будет использовать MapReduce или реализовать логику в коде приложения.

+0

Я надеялся на что-то с подстановочным знаком или что-то в этом роде, так что у меня не было бы самой длинной команды когда-либо, когда я добавлю все 24 поля к чему-то вложенному документу – DiMono

+0

@DiMono: согласно комментарию в конце моего ответа, MapReduce или логика приложения, вероятно, является более подходящим решением. В исходном вопросе упоминаются только элементы 0/1/2, но если у вас есть 24 поля, структура агрегации будет довольно многословной. Если вы делаете только этот расчет в одном документе (или нескольких документах), вероятно, наиболее эффективным будет просто перебрать документы в логике вашего приложения. Если вам нужно выполнить расчет по целому ряду документов, это будет способствовать использованию MapReduce. – Stennie

+0

Конечно, вы всегда можете создать конвейер Aggregation Framework программно, так что вам не нужно самостоятельно выписывать 24 поля. Это все еще слишком много для одного документа. В зависимости от того, как часто вам нужно запускать этот запрос, еще один вариант рассмотрения - [предварительная агрегация] (http://docs.mongodb.org/manual/use-cases/pre-aggregated-reports/), чтобы вы могли корректировать суммы для ваших вложенных документов в те же обновления, которые устанавливают их значения. – Stennie

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