2016-06-08 2 views
3

У меня есть документы, хранящиеся в моей базе данных с точно такой же «схемой». Каждый документ имеет три значения поплавков (ключи «A», «B» и «C»), и мне нужно сделать вывод, что каждый документ проецируется как среднее из всех трех.Среднее из 3-х полей в том же документе

Мне также нужно разделить на 100, поэтому мои расчеты (A + B + C)/3/100. Насколько я понимаю, мне нужно проецировать каждый документ как другой результат, но $ group здесь бесполезно (поскольку я не усредняю ​​по всем документам, только каждый).

Мне нужно сначала написать это как команду MongoDB, а затем перевести ее на PHP. Я думаю, что я смогу сделать PHP часть, но то, что мне нужно немного помочь начать работу по фактической команды MongoDB ...

db.measurements.aggregate( ) 

Мои данные хранятся следующим образом:

{ "_id" : ObjectId(xxx), "A": 22.34, "B": 23.32, "C": 75.32, "device_id": 3 } 
{ "_id" : ObjectId(xxx), "A": 22.34, "B": 23.32, "C": 75.32, "device_id": 3 } 
{ "_id" : ObjectId(xxx), "A": 22.34, "B": 23.32, "C": 75.32, "device_id": 3 } 

Когда я отправить запрос GET, мне нужны данные, чтобы выйти следующим образом:

{ "_id" : ObjectId(xxx), "Average of A,B,C": 40.50, "device_id": 3 } 
{ "_id" : ObjectId(xxx), "Average of A,B,C": 40.50, "device_id": 3 } 
{ "_id" : ObjectId(xxx), "Average of A,B,C": 40.50, "device_id": 3 } 

После некоторых дальнейших исследований, кажется, агрегат не метод, который я должен использовать здесь? Было бы лучше, если бы я вычислил среднее значение в моей модели php перед вставкой в ​​мою базу данных и просто получил мои документы с помощью метода find()?

+0

Пожалуйста, покажите пример документа с ожидаемым выходом. – styvane

+0

Добавлен в исходное сообщение – ugotchi

ответ

5

То, что вы в основном нужно это один $project водопроводная агрегация - это вычислить среднее значение для Вас, используя имеющийся arithmetic operators и изменит результат в том же трубопроводе, чтобы получить поле как выражение вычисления ((A + B + C)/3)/100 (если вам нужен процент, то вам нужно размножаться вместо деления, то есть вычисление ((A + B + C)/3)*100). Суммарно объясняется следующей операции:

db.measurements.aggregate([ 
    { 
     "$project": {    
      "device_id": 1, 
      "Average of A,B,C": { 
       "$divide": { // (A + B + C)/3)/100 
        { 
         "$divide": [ // (A + B + C)/3 
          { "$add": [ "$A", "$B", "$C" ] }, // A + B + C 
          3 
         ] 
        }, 
        100 
       } 
      } 
     } 
    } 
]) 

Это, как говорится, это лучше делать тяжелые и сложные вычислительные задачи на прикладном уровне, и пусть Монго лучшие сделать его сохраняемости данных задач.

+0

Спасибо chridam. Вероятно, лучше всего я делаю эти средние вычисления в прикладном уровне и сохраняю их как дополнительные поля перед добавлением в db. – ugotchi

+0

@ggwc Не беспокойтесь. Не слишком уверен, хотя если бы это была опечатка в вашем вопросе; были ли вы умножены на 100, чтобы получить процент, который подразумевается вашим ожидаемым результатом, или расчет правилен, как и с делителем 100? – chridam

+0

yep, его не%. Спасибо за вашу помощь. – ugotchi

3

Начиная с MongoDB 3.2, мы можем использовать оператор $avg аккумуляторных с квадратными скобками [] непосредственно создавать новые поля массива в $project этапе сделать это эффективно.

Конечно, нам также нужен оператор арифметической агрегации для деления значения на 100.

db.measurements.aggregate(
    [ 
     { "$project": { 
      "result": { 
       "$divide": [ 
        { "$avg": [ "$a", "$b", "$c" ] }, 
        100 
       ] 
      } 
     }} 
    ] 
) 

Перевод в PHP дает:

db.measurements.aggregate(
    array(
     array("$project" => array( 
      "result" => array( 
       "$divide" => array(
        "$avg" => array("$a", "$b", "$c"), 
        100 
       ) 
      ) 
     )) 
    ) 
) 
+1

Приятный вариант на 3.2-уровне! – chridam

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