如何使用bulk.find().updateOne()更新文档内数组指定元素字段
批量更新MongoDB数组中指定元素的字段问题
问题场景
我有一个Vendors集合,每个文档包含vendor_category数组字段,需要批量更新数组中_id匹配的元素的name和slug字段,使用UnorderedBulkOp操作后无报错,但数据没有任何变更。
数据示例
[{ "_id": { "$oid": "64663f4ec3560b33e85dd07d" }, "featured": "no", "protocol": "http://", "vendor_category": [ { "_id": { "$oid": "646515f6a120635ddce14e7d" }, "name": "News Articles", "slug": "news-articles", "status": "active", "created_ts": "2023-05-17T17:59:18.635Z" }, { "_id": { "$oid": "64679a1af8a58923f84c8ffb" }, "name": "Guardian Groups", "slug": "guardian-groups", "status": "active", "created_ts": "2023-05-19T15:47:38.867Z" } ], "name": "Assumenda dolor nobi" }]
尝试的代码(无变更效果)
let arr = results.map(e => e._id) const bulkOp = Facility.db.initializeUnorderedBulkOp() for (let a = 0; a < arr.length; a++) { bulkOp.find({'_id': mongojs.ObjectId(arr[a])}) // a = 64663f4ec3560b33e85dd07d .updateOne({$set: { 'vendor_category.$.name': req.body.name, 'vendor_category.$.slug': req.body.slug }}, { upsert: true }) } bulkOp.execute()
问题原因
- 使用数组位置操作符
$时,必须在find条件中同时指定数组元素的匹配规则(即vendor_category._id),否则MongoDB无法定位到数组中要更新的目标元素,$无法生效,导致更新操作无实际效果。 upsert: true的参数位置错误,且本次场景是更新已有文档,无需设置upsert。
修正后的代码
假设要更新的分类ID为req.body.categoryId,修正后的代码如下:
let arr = results.map(e => e._id) // 转换目标分类ID为ObjectId类型 const targetCategoryId = mongojs.ObjectId(req.body.categoryId) const bulkOp = Facility.db.initializeUnorderedBulkOp() for (let a = 0; a < arr.length; a++) { bulkOp.find({ '_id': mongojs.ObjectId(arr[a]), // 新增数组元素匹配条件,让$能定位到目标元素 'vendor_category._id': targetCategoryId }) .updateOne({ $set: { 'vendor_category.$.name': req.body.name, 'vendor_category.$.slug': req.body.slug } }) } // 执行批量操作并处理结果 bulkOp.execute((err, result) => { if (err) { console.error('批量更新失败:', err) // 此处添加错误处理逻辑 } else { console.log('批量更新成功:', result) // 此处添加成功处理逻辑 } })
期望输出
[{ "_id": { "$oid": "64663f4ec3560b33e85dd07d" }, "featured": "no", "protocol": "http://", "vendor_category": [ { "_id": { "$oid": "646515f6a120635ddce14e7d" }, "name": "News Articles", "slug": "news-articles", "status": "active", "created_ts": "2023-05-17T17:59:18.635Z" }, { "_id": { "$oid": "64679a1af8a58923f84c8ffb" }, "name": "Guardian Group", "slug": "guardian-group", "status": "active", "created_ts": "2023-05-19T15:47:38.867Z" } ], "name": "Assumenda dolor nobi" }]
内容的提问来源于stack exchange,提问作者Xander
相关产品推荐
相关产品推荐

