fli*_*erg 13 javascript database mongodb
当使用MongoDB时,我正在进行条件upsert作为聚合过程的一部分,在表单上(简化了很多):
db.dbname.update({attr1 : value1, attr2 : value2},
{"$inc" : { avg : current_value, nr : 1}},
false (multi), true (upsert))
Run Code Online (Sandbox Code Playgroud)
但我希望能够保持最大(和最小)值,而无需检索文档.有点像:
db.dbname.update({ attr1 : value1, attr2 : value2},
{"$inc" : { avg : current_value, nr : 1},
"$setIfBigger" : { max : current_value}},
false (multi), true (upsert))
Run Code Online (Sandbox Code Playgroud)
这有可能以有效的方式实现吗?
我当前的,效率极低的解决方案是我检查当前的聚合文档,如果它存在,我相应地更新值,如果不存在,我创建一个新文档.示例(再次,简化了很多,但实质是那里):
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});
}
Run Code Online (Sandbox Code Playgroud)
实际的程序是用Java编写的,使用的是mongo-API,聚合过程非常复杂,使用Javascript以外的组合技术与其他服务器通信,ergo mapreduce不是一个选项.最后,最终结果是一组非常庞大的简单值,我希望以最有效的方式存储这些值,并存储预先计算的平均值,某些组合的最大值和最小值.
一个解决方案是在JS中为每个更新创建独特的函数对象,我认为这不是一种有效的方法吗?
主要目标是减少执行此类聚合所需的时间,带宽使用是次要的.
hel*_*lmy 15
现在可以在包含插入和更新改进的MongoDB 2.6版本中更轻松地完成此操作.具体来说,有新的$ min和$ max运算符执行条件更新,具体取决于指定值的相对大小和字段的当前值.
例如这个更新:
db.scores.update( { _id: 1 }, { $max: { highScore: 950 } } )
Run Code Online (Sandbox Code Playgroud)
如果950大于当前值,则会有条件地更新指定的文档highScore
.