如何在Mongoose的updateMany操作中为不同文档随机设置payment_settlement值
解决方案
你之前的实现之所以所有文档取值相同,是因为Math.random()是在Node.js端仅计算一次,计算完成后的固定值才被传递给updateMany,自然所有文档都会被设置为同一个值。可以根据你的MongoDB版本选择对应方案:
方案一(推荐,MongoDB 4.4及以上版本适用)
使用MongoDB服务端的聚合管道更新能力,利用服务端内置的$rand函数为每个文档单独生成随机值,全程只需要发起一次批量更新请求,性能最优。
实现代码如下:
router.post("/payment_settlement", (req, res, next) => { models.Payment.updateMany( {}, // 可按需补充过滤条件,不填则匹配所有文档 [ { $set: { payment_settlement: { $cond: { if: { $lt: [{ $rand: {} }, 0.5] }, then: "pending", else: "settled" } } } } ] ) .then(result => funcs.sendSuccess(res, result)) .catch(next); });
方案二(兼容低版本MongoDB)
如果你的MongoDB版本低于4.4,不支持聚合管道更新和$rand函数,可以先拉取所有待更新文档的ID,用bulkWrite批量提交每个文档的独立更新请求。
实现代码如下:
router.post("/payment_settlement", async (req, res, next) => { const statusOptions = ["pending", "settled"]; try { // 仅拉取文档ID,降低内存占用 const paymentList = await models.Payment.find({}, { _id: 1 }).lean(); // 组装批量更新操作 const updateOps = paymentList.map(item => ({ updateOne: { filter: { _id: item._id }, update: { $set: { payment_settlement: statusOptions[Math.floor(Math.random() * 2)] } } } })); // 执行批量操作 const result = await models.Payment.bulkWrite(updateOps); return funcs.sendSuccess(res, result); } catch (err) { next(err); } });
如果待更新的存量数据量超过10万条,建议分批拉取ID、分批执行bulkWrite,避免内存溢出。
内容的提问来源于stack exchange,提问作者5war00p
相关产品推荐
相关产品推荐

