【发布时间】:2017-08-03 10:38:45
【问题描述】:
当使用 MongoDB 时,我目前正在做一个条件 upsert 作为聚合过程的一部分,在表单上(很多简化):
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 中为每次更新创建唯一的函数对象,我认为这不是一种有效的方法?
主要目标是减少执行此类聚合所需的时间,带宽使用是次要的。
【问题讨论】:
标签: javascript mongodb database