Multiply field by value in Mongodb

后端 未结 4 876
旧时难觅i
旧时难觅i 2020-12-01 03:15

I\'ve been looking for a way to create an update statement that will take an existing numeric field and modify it using an expression. For example, if I have a field called

相关标签:
4条回答
  • 2020-12-01 03:17

    Well, this is possible with an atomic operation as $set.

    You have several options :

    • use the eval() solution proposed by pingw33n
    • retrieve the document you want to modify to get the current value and modify it with a set
    • if you have a high operation rate, you might want to be sure the focument has not changed during you fetch its value (using the previous solution) so you might want to use a findAndModify (see this page to get inspired on how to do it) operation.

    It really depends on your context : with a very low pressure on the db, I'd go for the solution of pingw33n. With a very high operation rate, I'd use the third solution.

    0 讨论(0)
  • 2020-12-01 03:23

    In the new Mongo 2.6.x there is a $mul operator. It would multiply the value of the field by the number with the following syntax.

    {
      $mul: { field: <number> }
    }
    

    So in your case you will need to do the following:

    db.collection.update(
      { tag : "refurb"},
      { $mul: { Price : 0.5 } }
    );
    
    0 讨论(0)
  • 2020-12-01 03:42

    Starting Mongo 4.2, db.collection.update() can accept an aggregation pipeline, finally allowing the update of a field based on another field:

    // { price: 19.99 }
    // { price: 2.04  }
    db.collection.update(
      {},
      [{ $set: { price: { $multiply: [ 0.5, "$price" ] } } }],
      { multi: true }
    )
    // { price: 9.995 }
    // { price: 1.02  }
    
    • The first part {} is the match query, filtering which documents to update (all documents in this case).

    • The second part [{ $set: { price: ... } }] is the update aggregation pipeline (note the squared brackets signifying the use of an aggregation pipeline). $set is a new aggregation operator and an alias of $addFields. Note how price is modified directly based on the its own value ($price).

    • Don't forget { multi: true }, otherwise only the first matching document will be updated.

    0 讨论(0)
  • 2020-12-01 03:43

    You can run server-side code with db.eval().

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

    Note this will block the DB, so it's better to do find-update operation pair.

    See https://docs.mongodb.com/manual/core/server-side-javascript/

    0 讨论(0)
提交回复
热议问题