AWS DocumentDB(MongoDB3.6)数组子字段mId转数组的报错解决
问题:AWS DocumentDB(兼容MongoDB 3.6.0)批量转换数组元素字段类型
我的AWS DocumentDB(兼容MongoDB 3.6.0)集合中文档包含appliedRules数组,示例文档如下:
{ "_id" : ObjectId("63fcb6654732c97e476e642d"), "name" : "test1", "appliedRules" : [ { "id" : "rul1", "type" : "RULE_TYPE_1" }, { "id" : "rul1", "type" : "RULE_TYPE_2" }, { "id" : "rul1", "type" : "RULE_TYPE_2", "mId" : NumberInt(10006) } ] }
需求:将集合中所有appliedRules元素里,type为RULE_TYPE_2且存在整数类型mId的元素,把mId从整数转为数组类型。
我尝试了以下代码但执行报错:
MongoServerError: Wrong type for parameter u
db.reports_new_test.updateMany( { $and: [ { 'appliedRules.type': "RULE_TYPE_2" }, { 'appliedRules.mid': { $exists: true } } ] }, [ { $set: { 'appliedRules': { $map: { input: '$appliedRules', as: 'rule', in: { $mergeObjects: [ '$$rule', { mid: { $cond: { if: { $isArray: "$$rule.mid" }, then: "$$rule.mid", else: [ "$$rule.mid" ] } } } ] } } } } } ] );
解决方法
问题根源
- 字段名大小写错误:文档中字段是
mId(首字母大写),但查询和更新代码里用的是mid,MongoDB/DocumentDB对字段名大小写敏感,导致匹配逻辑错误。 - 版本特性不兼容:用聚合管道作为
updateMany的更新参数是MongoDB 4.2及以上才支持的特性,而你的DocumentDB兼容3.6版本,不支持该语法,这是报错的核心原因。
正确代码
使用find配合forEach循环更新每个符合条件的文档,这是MongoDB 3.6支持的传统更新方式:
db.reports_new_test.find({ "appliedRules": { "$elemMatch": { "type": "RULE_TYPE_2", "mId": { "$exists": true, "$not": { "$type": "array" } } } } }).forEach(function(doc) { // 遍历数组,修改符合条件的元素 var updatedAppliedRules = doc.appliedRules.map(function(rule) { if (rule.type === "RULE_TYPE_2" && rule.mId != null && !Array.isArray(rule.mId)) { rule.mId = [rule.mId]; } return rule; }); // 更新当前文档 db.reports_new_test.updateOne( { "_id": doc._id }, { "$set": { "appliedRules": updatedAppliedRules } } ); });
代码说明
- 查询条件用
$elemMatch精准筛选出包含目标元素的文档,避免无意义遍历:匹配type=RULE_TYPE_2、mId存在且不是数组的元素。 - 对每个文档的
appliedRules数组逐个元素检查,仅修改符合条件的mId字段,保留其他元素和字段不变。 - 用
updateOne针对单个文档更新,确保操作的准确性和版本兼容性。
内容的提问来源于stack exchange,提问作者Rakesh D
相关产品推荐
相关产品推荐

