Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> MongoDB

MongoDB 替换 Array 中的特定值:使用 $set 和位置操作符 $

本文演示如何使用 $set 结合位置操作符 $ 替换 Array 中匹配条件的特定元素值。

创建示例数据

> db.replaceValueInArrayDemo.insertOne({"StudentScores":[45,56,78]});
{ "acknowledged" : true, "insertedId" : ObjectId("5cd7f0421a844af18acdffb7") }
> db.replaceValueInArrayDemo.insertOne({"StudentScores":[33,90,67]});
{ "acknowledged" : true, "insertedId" : ObjectId("5cd7f0521a844af18acdffb8") }

显示原始数据

> db.replaceValueInArrayDemo.find().pretty();
{ "_id" : ObjectId("5cd7f0421a844af18acdffb7"), "StudentScores" : [ 45, 56, 78 ] }
{ "_id" : ObjectId("5cd7f0521a844af18acdffb8"), "StudentScores" : [ 33, 90, 67 ] }

替换第一个文档中值为 45 的元素为 99

> db.replaceValueInArrayDemo.update(
  { _id: ObjectId("5cd7f0421a844af18acdffb7"), StudentScores: 45 },
  { $set: { 'StudentScores.$': 99 } }
);
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

验证结果

> db.replaceValueInArrayDemo.find().pretty();
{ "_id" : ObjectId("5cd7f0421a844af18acdffb7"), "StudentScores" : [ 99, 56, 78 ] }
{ "_id" : ObjectId("5cd7f0521a844af18acdffb8"), "StudentScores" : [ 33, 90, 67 ] }

核心机制解析

  1. Query 部分: { _id: ..., StudentScores: 45 } - 同时匹配文档 _id 和 Array 中包含值 45
  2. 位置操作符 $: StudentScores.$ - 定位到 Query 中匹配的 第一个 Array 元素位置
  3. $set: 将该位置的值设为 99

关键限制

  • 只更新 第一个匹配 的 Array 元素
  • Query 必须包含 Array Field 的精确值匹配(或 $elemMatch)
  • 不支持更新多个匹配元素(需用 Aggregation $map 或应用层循环)

现代替代方案 (MongoDB 3.6+): arrayFilters

// 更新所有值为 45 的元素
db.replaceValueInArrayDemo.updateMany(
  { _id: ObjectId("5cd7f0421a844af18acdffb7") },
  { $set: { "StudentScores.$[elem]": 99 } },
  { arrayFilters: [{ elem: 45 }] }
);

Array of Objects 场景

// 将 items 中 productId="P001" 的 price 改为 29.99
db.orders.updateOne(
  { "items.productId": "P001" },
  { $set: { "items.$.price": 29.99 } }
);

相关操作符对比

操作操作符说明
替换元素值$set + $精确替换匹配位置
修改对象内字段$set + ${$set: {"items.$.qty": 5}}
添加元素$push/$addToSet末尾添加
删除元素$pull/$pullAll按值/按数组删除
按位置删除$unset + $pull先置 null 再 pull null