使用MongoDB updateMany设置折扣价无变更 求解决方案
问题:updateMany设置商品折扣价无变更,匹配但未修改
场景重现
集合数据:
{ "_id":"634861c7ee495492da321b2b", "name": "new product int", "price": 333, "description": "sdsad", "quantity": "1", "category": "test", "MRP": 333 }, { "_id": "6357a1361e40021f6f71897a", "name": "New Product 01", "price": 458, "description": "", "quantity": "5", "category": "test", "MRP": 458 }
执行的updateMany语句:
db.collection.updateMany({category:"test"},[{ $set: { price: { $floor: { $subtract: [ "$price", { $multiply: [ { $divide: [ "$price", 100 ] }, 50 ] } ] } } } } ])
执行结果:
acknowledged: true, modifiedCount: 0, upsertedId: null, upsertedCount: 0, matchedCount: 2
问题原因
- 占位符未替换:语句中
db.collection是MongoDB的通用占位符,必须替换为你的实际集合名称(比如db.products),否则无法正确定位目标集合。 - 版本兼容性:管道式更新(数组形式的更新器)要求MongoDB版本≥4.2,若你的版本低于此,该语法会失效,导致数据无法修改。
- 原计算逻辑虽正确,但冗余的运算步骤不影响结果,并非核心问题。
解决方案
方案1:简化版管道式更新(适用于MongoDB 4.2+)
将5折计算逻辑简化为直接乘以0.5后取整,同时替换为实际集合名称:
db.your_collection_name.updateMany( { category: "test" }, [ { $set: { price: { $floor: { $multiply: ["$price", 0.5] } } } } ] )
注:将your_collection_name替换为你实际的集合名称
方案2:forEach循环逐个更新(适用于所有MongoDB版本)
若MongoDB版本过低,可通过循环遍历匹配文档并逐个更新:
db.your_collection_name.find({ category: "test" }).forEach(doc => { const newPrice = Math.floor(doc.price * 0.5); db.your_collection_name.updateOne( { _id: doc._id }, { $set: { price: newPrice } } ); })
注:将your_collection_name替换为你实际的集合名称
内容的提问来源于stack exchange,提问作者Ajay Asok
相关产品推荐
相关产品推荐

