在Mongodb中按字段乘以字段

Bra*_*rad 29 mongodb

我一直在寻找一种方法来创建一个更新语句,该语句将使用现有的数字字段并使用表达式对其进行修改.例如,如果我有一个名为Price的字段,是否可以进行将Price设置为现有值50%的更新?

所以,给定 { Price : 19.99 }

我想做 db.collection.update({tag : "refurb"}, {$set {Price : Price * 0.50 }}, false, true);

可以这样做,还是我必须将值读回客户端,修改,然后更新?我想问题就是可以在更新中使用表达式,并且它们可以引用正在更新的文档.

pin*_*33n 37

您可以使用运行服务器端代码db.eval().

db.eval(function() { 
    db.collection.find({tag : "refurb"}).forEach(function(e) {
        e.Price = e.Price * 0.5;
        db.collection.save(e);
    });
});
Run Code Online (Sandbox Code Playgroud)

请注意,这将阻止数据库,因此最好执行查找更新操作对.

请参阅https://docs.mongodb.com/manual/core/server-side-javascript/


Sal*_*ali 21

在新的Mongo 2.6.x中有一个$ mul运算符.它会使用以下语法将字段的值乘以数字.

{
  $mul: { field: <number> }
}
Run Code Online (Sandbox Code Playgroud)

因此,在您的情况下,您将需要执行以下操作:

db.collection.update(
  { tag : "refurb"},
  { $mul: { Price : 0.5 } }
);
Run Code Online (Sandbox Code Playgroud)


Xav*_*hot 5

开始Mongo 4.2db.collection.update()可以接受聚合管道,最后允许基于另一个字段更新一个字段:

// { price: 19.99 }
// { price: 2.04  }
db.collection.update(
  {},
  [{ $set: { price: { $multiply: [ 0.5, "$price" ] } } }],
  { multi: true }
)
// { price: 9.995 }
// { price: 1.02  }
Run Code Online (Sandbox Code Playgroud)
  • 第一部分{}是匹配查询,过滤要更新的文档(本例中为所有文档)。

  • 第二部分[{ $set: { price: ... } }]是更新聚合管道(注意方括号表示聚合管道的使用)。$set是一个新的聚合运算符,也是 的别名$addFields。注意如何price直接根据其自身值进行修改($price)。

  • 不要忘记{ multi: true },否则只会更新第一个匹配的文档。