在 Groovy(或 JOLT)中修改 JSON
Modifying JSON in Groovy (or JOLT)
我有一个简单的 JSON 看起来像:
{
"account_login" : "google@gmail.com",
"view_id" : 1868715,
"join_id" : "utm_campaign=toyota&utm_content=multiformat_sites&utm_medium=cpc&utm_source=facebook",
"start_date" : "2020-02-03",
"end_date" : "2020-08-30"
}
使用以下 Groovy 脚本 ():
def content = """
{
"account_login" : "google@gmail.com",
"view_id" : 1868715,
"join_id" : "utm_campaign=toyota&utm_content=multiformat_sites&utm_medium=cpc&utm_source=facebook",
"start_date" : "2020-02-03",
"end_date" : "2020-08-30"
}
"""
def slurped = new JsonSlurper().parseText(content)
def builder = new JsonBuilder(slurped)
builder.content.join_id = builder.content.join_id.split("\s*&\s*") //# to array
.collectEntries{
//# convert each item to map entry
String[] utmMarks = it.trim().split("\s*=\s*")
utmMarks[0] = [
"utm_medium" : "ga:medium",
"utm_campaign" : "ga:campaign",
"utm_source" : "ga:source",
"utm_content" : "ga:adContent",
"utm_term" : "ga:keyword",
].get( utmMarks[0] )
utmMarks
}
.findAll{
k,v-> k && v!=null //# filter out empty/null keys
}
//builder.content.filters = ...
println(builder.toPrettyString())
我会得到:
{
"account_login": "google@gmail.com",
"view_id": 1868715,
"join_id": {
"ga:campaign": "toyota",
"ga:adContent": "multiformat_sites",
"ga:medium": "cpc",
"ga:source": "facebook"
},
"start_date": "2020-02-03",
"end_date": "2020-08-30"
}
我想更新此脚本(或编写新脚本)并添加新的 属性: array filters
到上面修改的 json。预期输出:
{
"account_login":"google@gmail.com",
"view_id":1868715,
"join_id":{
"ga:campaign":"toyota",
"ga:adContent":"multiformat_sites",
"ga:medium":"cpc",
"ga:source":"facebook"
},
"start_date":"2020-02-03",
"end_date":"2020-08-30",
"converted_utm_marks":"ga:campaign=toyota&ga:adContent=multiformat_sites&ga:medium=cpc&ga:source=facebook",
"filters":[
{
"dimensionName":"ga:medium",
"operator":"EXACT",
"expressions":[
"cpc"
]
},
{
"dimensionName":"ga:adContent",
"operator":"EXACT",
"expressions":[
"multiformat_sites"
]
},
{
"dimensionName":"ga:campaign",
"operator":"EXACT",
"expressions":[
"toyota"
]
},
{
"dimensionName":"ga:source",
"operator":"EXACT",
"expressions":[
"facebook"
]
}
]
}
但问题是每个 JSON 的过滤器集会有所不同。这个集合直接依赖于 join_id
集合。如果 JSON join_id
将包含:
"join_id": {
"ga:campaign": "toyota",
"ga:keyword": "car"
}
filters
数组应该是:
[
{
"dimensionName":"ga:campaign",
"operator":"EXACT",
"expressions":[
"toyota"
]
},
{
"dimensionName":"ga:keyword",
"operator":"EXACT",
"expressions":[
"car"
]
}
]
operator
始终等于 EXACT
。 属性 dimensionName
- 是一个 join_id.propety
名字。 Expressions
是一个 join_id.property
值。因此,属性 filters
基于 join_id
,我需要遍历 join_id
属性 并构建具有所述结构的 filters
数组。如何达到预期的产出? JOLT 配置也很受欢迎。
我什至无法简单地遍历 join_id
地图:
slurped.join_id.each { println "Key: $it.key = Value: $it.value" }
我收到错误:
/home/jdoodle.groovy: 24: illegal colon after argument expression;
solution: a complex label expression before a colon must be parenthesized @ line 24, column 28.
.collect { [it.ga:campaign] }
更新
我发现了如何构建这个数组:
def array =
[
filters: slurped.join_id.collect {key, value ->
[
dimensionName: key,
operator: "EXACT",
expressions: [
value
]
]
}
]
我好像明白了:
def slurped = new JsonSlurper().parseText(content)
def builder = new JsonBuilder(slurped)
builder.content.filters = builder.content.join_id.collect {key, value ->
[
dimensionName: key,
operator: "EXACT",
expressions: [
value
]
]
}
有没有更好的解决方案?
def slurped = new JsonSlurper().parseText(content)
def builder = new JsonBuilder(slurped)
builder.content.filters = builder.content.join_id.collect {key, value ->
[
dimensionName: key,
operator: "EXACT",
expressions: [
value
]
]
}
我有一个简单的 JSON 看起来像:
{
"account_login" : "google@gmail.com",
"view_id" : 1868715,
"join_id" : "utm_campaign=toyota&utm_content=multiformat_sites&utm_medium=cpc&utm_source=facebook",
"start_date" : "2020-02-03",
"end_date" : "2020-08-30"
}
使用以下 Groovy 脚本 (
def content = """
{
"account_login" : "google@gmail.com",
"view_id" : 1868715,
"join_id" : "utm_campaign=toyota&utm_content=multiformat_sites&utm_medium=cpc&utm_source=facebook",
"start_date" : "2020-02-03",
"end_date" : "2020-08-30"
}
"""
def slurped = new JsonSlurper().parseText(content)
def builder = new JsonBuilder(slurped)
builder.content.join_id = builder.content.join_id.split("\s*&\s*") //# to array
.collectEntries{
//# convert each item to map entry
String[] utmMarks = it.trim().split("\s*=\s*")
utmMarks[0] = [
"utm_medium" : "ga:medium",
"utm_campaign" : "ga:campaign",
"utm_source" : "ga:source",
"utm_content" : "ga:adContent",
"utm_term" : "ga:keyword",
].get( utmMarks[0] )
utmMarks
}
.findAll{
k,v-> k && v!=null //# filter out empty/null keys
}
//builder.content.filters = ...
println(builder.toPrettyString())
我会得到:
{
"account_login": "google@gmail.com",
"view_id": 1868715,
"join_id": {
"ga:campaign": "toyota",
"ga:adContent": "multiformat_sites",
"ga:medium": "cpc",
"ga:source": "facebook"
},
"start_date": "2020-02-03",
"end_date": "2020-08-30"
}
我想更新此脚本(或编写新脚本)并添加新的 属性: array filters
到上面修改的 json。预期输出:
{
"account_login":"google@gmail.com",
"view_id":1868715,
"join_id":{
"ga:campaign":"toyota",
"ga:adContent":"multiformat_sites",
"ga:medium":"cpc",
"ga:source":"facebook"
},
"start_date":"2020-02-03",
"end_date":"2020-08-30",
"converted_utm_marks":"ga:campaign=toyota&ga:adContent=multiformat_sites&ga:medium=cpc&ga:source=facebook",
"filters":[
{
"dimensionName":"ga:medium",
"operator":"EXACT",
"expressions":[
"cpc"
]
},
{
"dimensionName":"ga:adContent",
"operator":"EXACT",
"expressions":[
"multiformat_sites"
]
},
{
"dimensionName":"ga:campaign",
"operator":"EXACT",
"expressions":[
"toyota"
]
},
{
"dimensionName":"ga:source",
"operator":"EXACT",
"expressions":[
"facebook"
]
}
]
}
但问题是每个 JSON 的过滤器集会有所不同。这个集合直接依赖于 join_id
集合。如果 JSON join_id
将包含:
"join_id": {
"ga:campaign": "toyota",
"ga:keyword": "car"
}
filters
数组应该是:
[
{
"dimensionName":"ga:campaign",
"operator":"EXACT",
"expressions":[
"toyota"
]
},
{
"dimensionName":"ga:keyword",
"operator":"EXACT",
"expressions":[
"car"
]
}
]
operator
始终等于 EXACT
。 属性 dimensionName
- 是一个 join_id.propety
名字。 Expressions
是一个 join_id.property
值。因此,属性 filters
基于 join_id
,我需要遍历 join_id
属性 并构建具有所述结构的 filters
数组。如何达到预期的产出? JOLT 配置也很受欢迎。
我什至无法简单地遍历 join_id
地图:
slurped.join_id.each { println "Key: $it.key = Value: $it.value" }
我收到错误:
/home/jdoodle.groovy: 24: illegal colon after argument expression;
solution: a complex label expression before a colon must be parenthesized @ line 24, column 28.
.collect { [it.ga:campaign] }
更新
我发现了如何构建这个数组:
def array =
[
filters: slurped.join_id.collect {key, value ->
[
dimensionName: key,
operator: "EXACT",
expressions: [
value
]
]
}
]
我好像明白了:
def slurped = new JsonSlurper().parseText(content)
def builder = new JsonBuilder(slurped)
builder.content.filters = builder.content.join_id.collect {key, value ->
[
dimensionName: key,
operator: "EXACT",
expressions: [
value
]
]
}
有没有更好的解决方案?
def slurped = new JsonSlurper().parseText(content)
def builder = new JsonBuilder(slurped)
builder.content.filters = builder.content.join_id.collect {key, value ->
[
dimensionName: key,
operator: "EXACT",
expressions: [
value
]
]
}