我有这个特殊情况,我必须根据同一文档中存在的不同属性更新MongoDB中的某些值。所以我试图将findAndUpdate用于将传递JavaScript函数的where运算符,我也将使用其中一个属性作为查找条件。但是在MongoDB文档中已经提到过,在由于性能问题而无法避免之前,不应该使用where运算符。
现在假设我的文档中有3个属性id,counter1,counter2,我只在counter1 + counter2 = 2
时将counter1更新为1。所以我会写一些像
db.mydb.findAndUpdate({"_id" : id, $where : function() {
this.counter1 + this.counter2 == 2 ;}},
{$inc : {counter1 : 1}})
现在我的问题是:
答案 0 :(得分:2)
因此$where
评估的主要问题是条件逻辑无法处理“索引”以过滤匹配。此外,它毕竟是JavaScript逻辑,需要进行编译,并且需要从本机表单中进行“对象转换”,以便与JavacScript引擎中的评估一起使用。
所以它的使用应该“非常谨慎”,并且只有在“绝对”需要的时候,因为没有其他实用的方法。在你的情况下,这是一个“更新”操作,因此如果你需要那个逻辑那么好。如果它只是一个“查询”,那么我会说在聚合框架中使用$redact
代替:
db.mydb.aggregate([
{ "$match": { "_id": id } } },
{ "$redact": {
"$cond": {
"if": {
"$eq": [
{ "$add": [ "$counter1", "$counter2" ] },
2
]
},
"then": "$$KEEP",
"else": "$$PRUNE"
}
}}
])
因为这至少在本地运营商中都是如此,因此比JavaScript工作得更快。
至于“表现”,那都是相对的。但是,在_id
是“唯一”查找的情况下,实际性能“命中”应该可以忽略不计,因为已经对主键的“索引”进行了“完全匹配”。
这是$where
条件的一般建议。在那里你通常与其他本地查询运算符一起“使用它们”,这些运算符执行过滤的“批量”。然后,如果在JavaScript逻辑中应用条件需要更多的CPU周期(并且由于没有其他方法,它是绝对需要的),那么就这样吧。
但是,如果您的基于JavaScript的条件需要在没有其他过滤的帮助下扫描许多文档,那么这确实很糟糕。