简体   繁体   中英

How to perform a multiplication operation with an outside value and a value within the field while doing updateMany in MongoDB

I am trying to update my user's data based on the value in their collection and data from other modules.

User Model:
{
 money: 0,
 stock: [{
  name: "Tasla",
  quantity: 10
 },
 {
  name: "SpaceY",
  quantity: 20
 }]
}

Stock Data:
{
  name: "Tasla",
  price: 100
}

With these data, I am attempting to remove any user with a stock named "Tasla" from their stock array. While removing the object, I also want to add money into their money property, which should be "user.stock.quantity * stockData.price", But the problem is I don't know how to refer to the stock quantity while performing an updateMany().

Here is some of the attempt I've made:

User.updateMany({ "stock.name": { $eq: stockData.name } }, { $set: { "stock.$.quantity": 0 }, $set: { money: stockData.price * "$stock.quantity" } }, (err) => { if (err) console.error(err); });
-> Give cast error

//With aggregation
User.updateMany({ "stock.name": { $eq: stockData.name } }, [{ $set: { "stock.$.quantity": 0 }, $set: { "money": { $multiply: [stockData.price, "$stock.quantity"] } } }], (err) => {
      if (err) console.log(err);
});
-> Turns money into null. when replacing $stock.quantity with a simple integer, it works perfectly.

The query and '{ $set: { "stock.$.quantity": 0 }' works as intended, it is the '$set: { "money": { $multiply: [stockData.price, "$stock.quantity"] } }' I am not getting.

Any help would be greatly appreciated. Currently using Mongo v4.2.

I have figured out a horrendous yet working solution after many attempts.

User.updateMany(
      { stock: { $elemMatch: { name: stockData.name } } },
      [
        {
          $set: {
            money: {
              $add: [
                "$money",
                {
                  $multiply: [
                    stockData.price,
                    { $let: { vars: { total: { $arrayElemAt: ["$$ROOT.stock", { $indexOfArray: ["$$ROOT.stock.name", stockData.name] }] } }, in: { $sum: "$$total.quantity" } } },
                  ],
                },
              ],
            },
          },
        },
      ],
      {
        multi: true,
      }
    ).exec();

What I did is I found the position of the object that matches the description, then grabbed it using $arrayElemAt, then put it into $let so I can get the quantity property, then I simply multiply the quantity by stockData Price, then add it with original money value.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM