使用 MongoDB 时,我目前正在表单上进行条件更新插入,作为聚合过程的一部分(简化了很多):
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))
这可以以有效的方式实现吗?
我当前效率极低的解决方案是检查当前聚合文档,如果存在,则相应地更新值,如果不存在,则创建一个新文档。示例(同样,简化了很多,但本质就在那里):
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的组合技术与其他服务器通信,因此mapreduce不是一个选择。最后的最终结果是一组巨大的简单值,我想以最有效的方式存储它们,并存储预先计算的平均值、某些组合的最大值和最小值。
一种解决方案是在 JS 中为每次更新创建唯一的函数对象,我认为这不是一种有效的方法?
主要目标是减少执行此类聚合所需的时间,带宽使用是次要的。