При использовании MongoDB я в настоящее время выполняю условный upsert как часть процесса агрегации, в форме (упрощенной alot):
db.dbname.update({attr1 : value1, attr2 : value2},
{"$inc" : { avg : current_value, nr : 1}},
false (multi), true (upsert))
Но я хочу также сохранить максимальное (и минимальное) значение, не получая документ. Что-то вроде:
db.dbname.update({ attr1 : value1, attr2 : value2},
{"$inc" : { avg : current_value, nr : 1},
"$setIfBigger" : { max : current_value}},
false (multi), true (upsert))
Возможно ли это эффективно?
Мое текущее, крайне неэффективное решение заключается в том, что я проверяю текущий документ агрегирования, и если он существует, я обновляю значения соответствующим образом, и если это не так, я создаю новый документ. Пример (опять же, упрощенный alot, но суть есть):
var obj = db.dbname.findOne({attr1 : value1, attr2 : value2},{_id:1});
if (obj != null) {
db.dbname.update({attr1 : value1, attr2 : value2},
{"$inc" : { avg : current_value, nr : 1},
"$set" : { max : (obj.max > current_value ? obj.max : current_value}},
false (multi), true (upsert));
} else {
db.dbname.save({attr1 : value1, attr2 : value2,
avg : current_value, nr : 1,
max : current_value});
}
Фактическая программа написана на Java и использует mongo-API, а процесс агрегации довольно сложный и использует методы композиций вне Javascript для связи с другими серверами, ergo mapreduce - это не вариант. Наконец, конечный результат представляет собой довольно сложный набор простых значений, которые я хочу сохранить наиболее эффективным образом, а также сохранить заранее рассчитанные средние значения, максимумы и минимумы определенных комбинаций.
Одно из решений - создавать уникальные функциональные объекты в JS для каждого отдельного обновления, которое, я считаю, не является эффективным способом?
Основная цель - уменьшить время, затраченное на выполнение агрегации этого типа, использование полосы пропускания является вторичным.