如何通过MongoDB将JSON数组转换为预定义键的键值对
解决MongoDB数组元素映射预定义字段名的问题
现有MongoDB文档结构如下:
{ "_id": { "$oid": "654e74b1325312179d479295" }, "myid": "id123", "array": [7, 98, 2, 35, 76] }
数组元素按位置对应预定义字段名列表 ["val0", "val1", "val2", "val3", "val4"],需要将原数组转换成 [{"val0":7}, {"val1":98}, ...] 的结构,直接用MongoDB聚合完成转换的方案如下:
完整聚合管道
db.array_test.aggregate([ { $match: { myid: "id123" } }, { $addFields: { zipped: { $zip: { inputs: ["$array", ["val0", "val1", "val2", "val3", "val4"]], useLongestLength: true } } } }, { $unwind: "$zipped" }, { $addFields: { mappedObj: { $arrayToObject: [[{ k: { $arrayElemAt: ["$zipped", 1] }, v: { $arrayElemAt: ["$zipped", 0] } }]] } } }, { $group: { _id: "$_id", myid: { $first: "$myid" }, array: { $push: "$mappedObj" } } } ])
步骤解释
- $match:过滤出目标文档,和你原来的用法一致。
- $addFields + $zip:用
$zip将原array数组和预定义字段名数组按位置配对,生成[[7, "val0"], [98, "val1"], ...]这样的二维数组,确保每个值和对应的字段名绑定。 - $unwind:把配对后的二维数组拆分成单个文档,每个文档包含一组
[值, 字段名]数据。 - $addFields + $arrayToObject:将每组配对转换成指定格式的对象。先用
$arrayElemAt分别取出字段名(索引1)和值(索引0),再通过$arrayToObject把键值对数组转成{val0:7}这类对象。 - $group:按原文档
_id重新分组,组装myid和转换后的array数组,得到最终需要的结构。
执行结果
[ { "_id": { "$oid": "654e74b1325312179d479295" }, "myid": "id123", "array": [ { "val0": 7 }, { "val1": 98 }, { "val2": 2 }, { "val3": 35 }, { "val4": 76 } ] } ]
你之前的聚合只拆分了数组元素,但没有关联预定义的字段名,所以只能生成固定label键的对象。这个方案通过$zip关联位置对应的字段名,再动态生成键,完美匹配你的需求。
内容的提问来源于stack exchange,提问作者Marco R
相关产品推荐
相关产品推荐

