MongoDB中如何重命名数组内嵌文档中的指定字段?
MongoDB数组内嵌文档字段重命名解决方案
需求:将文档数组parserErgebnis下values子文档中的字段NUTZERKENNUNGAUFTRAGGEBER重命名为ORDNUNGSBEGRIFFAUFTRAGGEBER,同时保留values中的其他字段。
原始数据示例
[ { "parserErgebnis": [ { "values": { "NUTZERKENNUNGAUFTRAGGEBER": { "status": "OK", "wert": "1000/13138/1082" }, "ANYTHING": "bla", "BLUBB": "bla" } } ] }, { "parserErgebnis": [ { "values": { "NUTZERKENNUNGAUFTRAGGEBER": { "status": "OK", "wert": "1000/13138/1083" } } } ] }, { "parserErgebnis": [ { "values": { "ORDNUNGSBEGRIFFAUFTRAGGEBER": { "status": "OK", "wert": "1000/13138/1084" } } } ] } ]
预期结果
[ { "parserErgebnis": [ { "values": { "ORDNUNGSBEGRIFFAUFTRAGGEBER": { "status": "OK", "wert": "1000/13138/1082" }, "ANYTHING": "bla", "BLUBB": "bla" } } ] }, { "parserErgebnis": [ { "values": { "ORDNUNGSBEGRIFFAUFTRAGGEBER": { "status": "OK", "wert": "1000/13138/1083" } } } ] }, { "parserErgebnis": [ { "values": { "ORDNUNGSBEGRIFFAUFTRAGGEBER": { "status": "OK", "wert": "1000/13138/1084" } } } ] } ]
问题分析
之前尝试的update语句无法正常工作:指定parserErgebnis.values.ORDNUNGSBEGRIFFAUFTRAGGEBER作为键会报错,仅写ORDNUNGSBEGRIFFAUFTRAGGEBER则会丢失values子文档的原有结构。错误语句如下:
db.collection.update({ "parserErgebnis.values.NUTZERKENNUNGAUFTRAGGEBER": { $exists: true } }, [ { $addFields: { parserErgebnis: { $map: { input: "$parserErgebnis", as: "parserErgebnis", in: { "parserErgebnis.values.ORDNUNGSBEGRIFFAUFTRAGGEBER": "$$parserErgebnis.values.NUTZERKENNUNGAUFTRAGGEBER" } } } } } ], { multi: true })
可行解决方案
使用$map遍历parserErgebnis数组,对每个元素中的values子文档,通过$mergeObjects合并原有字段与新命名的字段,再用$unset逻辑移除旧字段。完整update语句如下:
db.collection.update({ "parserErgebnis.values.NUTZERKENNUNGAUFTRAGGEBER": { $exists: true } }, [ { $addFields: { parserErgebnis: { $map: { input: "$parserErgebnis", as: "item", in: { values: { $mergeObjects: [ "$$item.values", { ORDNUNGSBEGRIFFAUFTRAGGEBER: "$$item.values.NUTZERKENNUNGAUFTRAGGEBER" }, { NUTZERKENNUNGAUFTRAGGEBER: "$$REMOVE" } ] } } } } } } ], { multi: true })
原理说明
- 匹配条件:仅更新包含目标旧字段的文档,避免无意义操作。
- $map遍历数组:逐个处理
parserErgebnis中的每个元素。 - $mergeObjects合并字段:
- 保留
values中的原有所有字段; - 添加新命名的字段,值取自旧字段;
- 使用
$$REMOVE标记移除旧字段。
- 保留
- multi: true:确保更新所有符合条件的文档。
内容的提问来源于stack exchange,提问作者jens_laufer
相关产品推荐
相关产品推荐

