如何在MongoDB中更新数组内文档,添加data3字段并赋值
MongoDB为数组元素添加指定字段的实现方案
问题背景
现有MongoDB文档结构如下:
[ { "username": "joy", "size_info": [ { "data1": "apple bear cat", "data2": 100 }, { "data1": "dog eat fog good ", "data2": 100 }, { "data1": "hug ill jump", "data2": 100 } ] } ]
需求是为size_info数组中的每个元素添加data3字段,其值为data1按空格拆分后的前两个单词,最终目标文档结构如下:
[ { "username": "joy", "size_info": [ { "data1": "apple bear cat", "data2": 100, "data3": "apple bear" }, { "data1": "dog eat fog good ", "data2": 100, "data3": "dog eat" }, { "data1": "hug ill jump", "data2": 100, "data3": "hug ill" } ] } ]
尝试使用$substr操作时,出现错误:
can't convert from BSON type array to String
错误原因
该错误是因为$substr仅支持处理字符串类型,若先对data1用$split拆分得到数组后,直接用$substr操作数组,就会触发类型不匹配的报错。
需求可实现,以下是具体方案
方案一:MongoDB 4.2+ 聚合管道更新(推荐)
MongoDB 4.2及以上版本支持在更新操作中使用聚合管道,可直接对数组元素做批量处理:
db.collection.updateMany( {}, [ { $set: { size_info: { $map: { input: "$size_info", as: "item", in: { $mergeObjects: [ "$$item", { data3: { $reduce: { input: { $slice: [{ $split: ["$$item.data1", " "] }, 2] }, initialValue: "", in: { $cond: [ { $eq: ["$$value", ""] }, "$$this", { $concat: ["$$value", " ", "$$this"] } ] } } } } ] } } } } } ] )
方案二:MongoDB 4.4+ 简化版
若使用MongoDB 4.4及以上版本,可借助$arrayToString简化拼接逻辑:
db.collection.updateMany( {}, [ { $set: { size_info: { $map: { input: "$size_info", as: "item", in: { $mergeObjects: [ "$$item", { data3: { $arrayToString: { input: { $slice: [{ $split: ["$$item.data1", " "] }, 2] }, separator: " " } } } ] } } } } } ] )
核心逻辑说明
$split:将data1按空格拆分为单词数组$slice:截取数组的前两个元素$arrayToString/$reduce:将截取后的数组拼接为空格分隔的字符串$map:遍历size_info数组,对每个元素执行处理$mergeObjects:将原元素属性与新增的data3字段合并
内容的提问来源于stack exchange,提问作者jexists
相关产品推荐
相关产品推荐

