MongoDB中$arrayToObject遇重复键如何拆分生成独立文档?
MongoDB聚合:将成对的module与data封装为独立文档
针对你遇到的重复键被覆盖问题,可通过以下聚合管道实现将每组module和对应data封装为独立文档:
完整聚合管道
[ { $project: { type: "$logs.events.type", attributePairs: { // 按每2个元素为一组,生成module-data配对数组 $reduce: { input: { $range: [0, { $size: "$logs.events.attributes" }] }, initialValue: [], in: { $cond: [ { $eq: [{ $mod: ["$$this", 2] }, 0] }, { $concatArrays: ["$$value", [[{ $arrayElemAt: ["$logs.events.attributes", "$$this"] }, { $arrayElemAt: ["$logs.events.attributes", { $add: ["$$this", 1] }] }]]], "$$value" ] } } } } }, { $unwind: "$attributePairs" }, // 将每组配对拆分为独立文档 { $project: { logs: { events: { type: "$type", attributes: { $arrayToObject: { $map: { input: "$attributePairs", as: "item", in: { k: "$$item.key", v: "$$item.value" } } } } } } } } ]
步骤拆解
生成配对数组:
用$range生成attributes数组的索引序列,再通过$reduce筛选偶数索引(从0开始),将当前索引与下一个索引对应的元素组成module-data对,最终得到包含所有配对的attributePairs数组。拆分独立文档:
通过$unwind将attributePairs数组拆分为单个文档,每个文档对应一组module-data配对。重构目标结构:
使用$map和$arrayToObject将每组键值对转换为对象,再嵌套回原有的logs.events层级,得到符合要求的输出。
最终输出
执行上述管道后,将得到如下结果:
[ { "logs": { "events": { "type": "call_action", "attributes": { "module": "module1", "data": "data_value_module_1" } } } }, { "logs": { "events": { "type": "call_action", "attributes": { "module": "module2", "data": "data_value_module_2" } } } } ]
(若需将data键改为value,可在$map阶段添加$cond判断:当$$item.key为data时,将k设为"value"即可)
内容的提问来源于stack exchange,提问作者angel
相关产品推荐
相关产品推荐

