我们应该多久使用一次MongoDB的where操作符
我有一个特殊的场景,我必须根据同一文档中存在的不同属性更新MongoDB中的某些值。所以我尝试使用findAndUpdate和where操作符,它将被传递给一个JavaScript函数,我还将使用其中一个属性作为查找条件。但MongoDB文档中提到,除非由于性能问题无法避免,否则不应使用where操作符 现在让我们假设我的文档中有3个属性id,counter1,counter2,并且只有当我们应该多久使用一次MongoDB的where操作符,mongodb,mongodb-query,Mongodb,Mongodb Query,我有一个特殊的场景,我必须根据同一文档中存在的不同属性更新MongoDB中的某些值。所以我尝试使用findAndUpdate和where操作符,它将被传递给一个JavaScript函数,我还将使用其中一个属性作为查找条件。但MongoDB文档中提到,除非由于性能问题无法避免,否则不应使用where操作符 现在让我们假设我的文档中有3个属性id,counter1,counter2,并且只有当counter1+counter2=2时,我才用1更新counter1。所以我会写一些类似的东西 db.my
counter1+counter2=2
时,我才用1更新counter1。所以我会写一些类似的东西
db.mydb.findAndUpdate({"_id" : id, $where : function() {
this.counter1 + this.counter2 == 2 ;}},
{$inc : {counter1 : 1}})
现在我的问题是:
db.mydb.aggregate([
{“$match”:{“_id”:id}},
{“$redact”:{
“$cond”:{
“如果”:{
“$eq”:[
{“$add”:[“$counter1”,“$counter2”]},
2.
]
},
“然后”:“$$KEEP”,
“else”:“$$PRUNE”
}
}}
])
因为这至少在本机操作符中都是如此,因此比JavaScript工作得更快
至于“表现”,则是相对的。但是,如果\u id
是一个“唯一”查找,那么实际性能“命中”应该可以忽略不计,因为主键的“索引”上已经完成了“精确匹配”
这是关于$where
条件的一般建议。在这种情况下,您通常会将它们与其他执行“大量”过滤的本机查询运算符结合使用。然后,如果在JavaScript逻辑中应用这些条件需要更多的CPU周期(这是绝对需要的,因为没有其他方法),那么就这样吧
但是,如果基于JavaScript的条件需要在没有其他筛选帮助的情况下扫描许多文档,那么这确实是不好的。非常谨慎,最好只与其他执行主筛选的本机查询操作符一起进行。顺便说一句,您的查询语法无效。我想您的意思是:
{“\u id”:id,“$where”:function(){}
才有效。是的,没错,更正了。确切地说,我是在问,因为本地查询运算符实际上是在执行主筛选的,在单个文档上使用where运算符会对性能产生任何影响吗?我想你也可能是指this.obj.counter
,除非你真的是指this.counter
,这取决于“counter1”是顶级还是在“obj”下就像普通查询中的“obj.counter1”。问题的第二部分有什么输入吗?上述查询是否会对性能产生任何影响?这部分称为“答案”,您现在已经知道了。当然会有影响,但这都与你实际做的事情有关。在这种情况下,差异是最小的,应该几乎看不到。您也可以在if
中使用$和,将管道缩短为$redact
。感谢详细的回答,因为我必须在我的案例中执行更新操作,所以我认为根据您的反馈,我的解决方案会很好。有没有其他方法可以更有效地执行更新操作?@user1776860没有,这里真的没有其他选择。正如我提到的,$where
在这样的更新条件下是有意义的。如果有一个主键,它将变得非常有效。$where
应该做并且已经做的唯一一件事就是“再次过滤”那些已经从索引中过滤的结果。@user3100115这实际上会导致“巨大”的性能下降。正如我在这里已经提到的,以及最近在另一个问题上向您提到的,“查询”选择的要点是“使用索引”过滤掉内容。这是$redact
而不是$where
单独使用时可能会做的事情。这就是条件分离的原因。