set a random values in a field using UpdateMany in mongoose query

Issue

I wanted to know whether this is possible that while updating many documents using UpdateMany in mongoose I need to set any of the status value from ["pending", "settled"] to a key called payment_settlement for different documents.

For better understanding I’m adding the route here:

router.post("/payment_settlement", (req, res, next) => {
    var ar = ["pending", "settled"];
    models.Payment.updateMany({ $set: { payment_settlement: ar[Math.floor(Math.random() * 2)] } })
        .then(_ => {
            return funcs.sendSuccess(res, _);
        })
        .catch(next);
});

The above approach gave me the same result for all documents either "pending" or "settled".
My doubt is that MongoDB(Mongoose) computing random value once at the beginning, and using that single random value for all documents.

However, we can achieve this using enum in mongoose schema. But I need to update existing documents with random values.

Any ideas or discussion is highly appreciated.

Thanks

Solution

Because you are using mongodb version 4.4.2 so you can use Updates with Aggregation Pipeline and $rand operator:

models.Payment.updateMany(
  {},
  [
    {
      $set: {
        payment_settlement: {
          $arrayElemAt: [
            ["pending", "settled"],
            { $round: { $rand: {} } }
          ]
        }
      }
    }
  ]
)

MongoPlayground

Or if your array have more than 2 elements, you can use $multiply with $rand:

models.Payment.updateMany(
  {},
  [
    {
      $set: {
        payment_settlement: {
          $arrayElemAt: [
            ["pending", "settled", "cancelled"],
            { $round: { $multiply: [{ $rand: {} }, 2] } }
          ]
        }
      }
    }
  ]
)

MongoPlayground

Answered By – Cuong Le Ngoc

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published