MongoDB基于嵌套数组生成动态字段名实现数据扁平化方案咨询
MongoDB聚合实现方案
以下聚合管道可以完全匹配你要求的转换规则,兼容不同长度、不同类型组合的traits数组:
db.collection.aggregate([ // 第一步:处理traits数组,生成格式化后的特征键值对 { $addFields: { processedTraits: { $arrayToObject: { $map: { input: { $group: { input: "$traits", key: { // 格式化trait_type:空格转下划线、全小写、拼接前缀 $concat: [ "traits_", $toLower: { $replaceAll: { input: "$$this.trait_type", find: " ", replacement: "_" } } ] }, accumulator: { $push: "$$this.value" } } }, as: "traitGroup", in: { k: "$$traitGroup.key", v: { // 单值直接返回,多值保留数组 $cond: { if: { $eq: [{ $size: "$$traitGroup.value" }, 1] }, then: { $first: "$$traitGroup.value" }, else: "$$traitGroup.value" } } } } } } } }, // 第二步:把特征字段合并到文档顶层 { $replaceRoot: { newRoot: { $mergeObjects: ["$$ROOT", "$processedTraits"] } } }, // 第三步:清理冗余字段 { $unset: ["processedTraits", "traits"] } ])
上述方案要求MongoDB版本 ≥ 5.2,如果你使用更低版本,可以用下面的兼容写法:
db.collection.aggregate([ { $addFields: { processedTraits: { $reduce: { input: "$traits", initialValue: {}, in: { $let: { vars: { key: { $concat: [ "traits_", $toLower: { $replaceAll: { input: "$$this.trait_type", find: " ", replacement: "_" } } ] }, currentVal: "$$this.value" }, in: { $cond: { if: { $not: ["$$value.$$key"] }, then: { $mergeObjects: ["$$value", { "$$key": "$$currentVal" }] }, else: { $mergeObjects: [ "$$value", { "$$key": { $cond: { if: { $isArray: "$$value.$$key" }, then: { $concatArrays: ["$$value.$$key", ["$$currentVal"]] }, else: ["$$value.$$key", "$$currentVal"] } } } ] } } } } } } } } }, { $replaceRoot: { newRoot: { $mergeObjects: ["$$ROOT", "$processedTraits"] } } }, { $unset: ["processedTraits", "traits"] } ])
兼容版本要求MongoDB ≥ 4.4,如需适配更低版本,仅需要把$replaceAll替换为$split+$reduce的拼接逻辑处理空格转下划线即可。
内容的提问来源于stack exchange,提问作者justinavery
相关产品推荐
相关产品推荐

