Groovy脚本处理JSON时仅取最后一个metrics值的修复咨询
Groovy脚本提取Metrics值缺失问题修复方案
常见问题原因
- 变量覆盖:遍历metrics时,每次重新赋值给同一个Map变量,导致之前的数值被覆盖,仅保留最后一个
- 索引不匹配:未正确使用索引关联
query.metrics和data.metrics的对应关系
修复示例代码
源JSON示例
{ "query": { "ids": ["counter_123"], "dimensions": ["date", "source"], "metrics": [ {"name": "sessions"}, {"name": "conversions", "goal_id": "goal_456"} ] }, "data": { "dimensions": ["2024-05-20", "organic"], "metrics": [1000, 50] } }
修复后的Groovy脚本
@Grab('org.codehaus.groovy:groovy-json:3.0.17') import groovy.json.JsonSlurper import groovy.json.JsonBuilder def jsonStr = '''上面的源JSON内容''' def sourceJson = new JsonSlurper().parseText(jsonStr) def result = [:] // 提取counter_id result.counter_id = sourceJson.query.ids[0] // 关联维度并映射字段名 def dimensionMap = [:] sourceJson.query.dimensions.eachWithIndex { dimName, idx -> dimensionMap[dimName] = sourceJson.data.dimensions[idx] } result.dimensions = dimensionMap // 关联metrics,保留所有值并处理goal_id def metricsMap = [:] sourceJson.query.metrics.eachWithIndex { metricDef, idx -> def metricValue = sourceJson.data.metrics[idx] if (metricDef.goal_id) { // 按goal_id命名conversions字段 metricsMap["conversions_${metricDef.goal_id}"] = metricValue } else { metricsMap[metricDef.name] = metricValue } } result.metrics = metricsMap // 输出格式化后的结果JSON println new JsonBuilder(result).toPrettyString()
关键修复点
- 遍历metrics时,向同一个Map中累加键值对,而非每次重新赋值覆盖整个Map
- 使用
eachWithIndex确保query.metrics中的每个定义,精准匹配data.metrics中对应索引的数值 - 针对带
goal_id的metrics,生成带ID后缀的字段名,避免键名冲突导致的覆盖
内容的提问来源于stack exchange,提问作者takotsubo
相关产品推荐
相关产品推荐

