mongodb + добавить поле + использовать другие поля для расчета + получить максимум

У меня есть следующие документы в mongodb (1 неделя почасовых данных для 2 узлов NodeA и NodeB)

> db.collection_name.find().pretty()
{
        "_id" : ObjectId("52979bc7ebf1a5ecb120ae65"),
        "Time" : "18/11/2013 0:00",
        "Node Name" : "NodeA",
        "Integrity" : "100%",
        "X_1" : 103674,
        "X_2" : 45,
        "X_3" : 13071,
        "X_4" : 103626,
        "X_5" : 46,
        "X_6" : 14639
}
{
        "_id" : ObjectId("52979bc7ebf1a5ecb120ae66"),
        "Time" : "18/11/2013 0:00",
        "Node Name" : "NodeB",
        "Integrity" : "100%",
        "X_1" : 103674,
        "X_2" : 45,
        "X_3" : 13071,
        "X_4" : 103626,
        "X_5" : 46,
        "X_6" : 14639
}

... 

{
        "_id" : ObjectId("52979bc7ebf1a5ecb120ae67"),
        "Time" : "24/11/2013 23:00",
        "Node Name" : "NodeA",
        "Integrity" : "100%",
        "X_1" : 103674,
        "X_2" : 45,
        "X_3" : 13071,
        "X_4" : 103626,
        "X_5" : 46,
        "X_6" : 14639
}
{
        "_id" : ObjectId("52979bc7ebf1a5ecb120ae68"),
        "Time" : "24/11/2013 23:00",
        "Node Name" : "NodeB",
        "Integrity" : "100%",
        "X_1" : 103674,
        "X_2" : 45,
        "X_3" : 13071,
        "X_4" : 103626,
        "X_5" : 46,
        "X_6" : 14639
}

Теперь я хочу создать новое поле с чем-то вроде этого:

db.students.update({},{$set :{"new_field_name":<values_of_new_dieldname>}},{upsert:false,multi:true})

в <values_of_new_dieldname> я хочу сделать (X_1 + X_3)*8/3600, давайте назовем это calcA, что даст что-то вроде: (на данном этапе мне все равно X1->x6)

{
        "_id" : ObjectId("52979bc7ebf1a5ecb120ae91"),
        "Time" : "24/11/2013 23:00",
        "Node Name" : "NodeA",
        "new_field_name": calcA
}
{
        "_id" : ObjectId("52979bc7ebf1a5ecb120ae90"),
        "Time" : "24/11/2013 23:00",
        "Node Name" : "NodeB",
        "new_field_name": calcA
}

а затем я хочу объединить «Имена узлов», чтобы получить сумму «new_field_name», которая даст что-то вроде:

_id {

        "Time" : "24/11/2013 23:00",
        "field_name": calcA + calcA  (from NodeA and NodeB)
}

поэтому у меня будет один из них для каждого часа с «18.11.2013 0:00» -> «24.11.2013 23:00» для этого примера.

а затем я хочу получить максимальное значение "имя поля"

Ну, это то, что я пытаюсь сделать, надеюсь, это ясно. В настоящее время я рассматриваю использование метода агрегации, чтобы попытаться достичь этого. был бы я прав с таким подходом.

Благодарность


person HattrickNZ    schedule 28.11.2013    source источник
comment
Этот вопрос очень специфичен. Меньший вариант использования был бы лучше.   -  person mikemaccana    schedule 17.06.2014
comment
Вы действительно не хотите хранить свое время в формате MM/DD/YYYY. Используйте ISODate().   -  person mcr    schedule 22.08.2014


Ответы (1)


Вы можете попробовать что-то вроде этого.

db.yourcollection.aggregate(
{ $group:
  {
    _id:"$Time",
        x1sum: {$sum:"$X_1"},
    X3sum: {$sum:"$X_3"}
  }
},

{ $project:
  {
    _id:1,
    calculation: {$divide:[[{$multiply:[{$add:["$x1sum","$x2sum"]},8}],3600]
  }  

});

Пожалуйста, перепроверьте синтаксис, потому что я не могу проверить его прямо сейчас, и он написан блокнотом, и там много фигурных скобок.

Как видите, он сначала группирует данные по времени, а затем выполняет математические операции в проекции.

При желании вы можете упорядочить результаты с помощью нового конвейера или использовать $max в новом групповом конвейере.

person rubenfa    schedule 29.11.2013