JOLT 中的条件 JSON 转换
conditional JSON transformation in JOLT
我需要处理来自 SOLR 服务的响应,如下所示:
{
"data": {
"distanceUnits": "mi", //it can be "mi", "MI", "miles", "km", "KM", etc.
"solrResponse": {
"header": {
"found": 32,
"retrieved": 10,
... //there can be other things like timestamp
},
"results": [
{
"matchScore": "08768",
"indicators" [{...}],
"location": {
... //there are about hundred attributes
"distance": "2.7649" //distance always in km
"similarity": "0.342"
},
...
]
}
转换需要 return 来自 solrResponse 的所有内容几乎完好无损,除了两件事:
- similarity 需要重命名为 similarityScore 并向上移动到 matchScore 旁边。
- 如果distanceUnit指定为英里,距离需要转换为英里(即除以1.609)
- 距离值四舍五入到小数点后2位,并与distanceUnit相连。
我创建了以下规范:
[
{
"operation": "modify-overwrite-beta",
"spec": {
"data": {
"unit1": "=toLower(@(1,distanceUnit))",
"unit2": "=substring(@(1,unit1),0,1)",
"solrResponse": {
"results": {
"": {
"dist1": "=divideAndRound(2,@(1,distance),0.6215)",
"distanceMiles": "=concat(@(1,dist1), ' ', @(2,distanceUnit))",
"dist2": "=divideAndRound(2,@(1,distance),1.0)",
"distanceKm": "=concat(@(1,dist2), ' ', @(2,distanceUnit))"
}
}
}
}
}
},
{
"operation": "shift",
"spec": {
"data": {
"solrResponse": {
"header": "&1",
"response": {
"": {
"&1.similarity": "similarityScore",
"unit2": {
"m": {
"distanceMiles": "locations.distance"
},
"": {
"distanceKm": "locations.distance"
}
},
"": "&1"
}
}
}
}
}
}
]
不幸的是,它不起作用。请帮助我。
Jolt 没有 multiply
或 product
等功能,但 divide
和 divideAndRound
可用于 修改 转换规范。然后,我们将有一个条件来过滤 distanceUnit
属性的提供值是否存在于列表 (mi,m,Mi,MI
) 中,例如
[
{
"operation": "modify-overwrite-beta",
"spec": {
"*": { // this outer one represents "locations" list(if there's no other outer level list or object, otherwise replace "*" with the key name "locations")
"*": { // this one stands for "locations" list's indexes
"distanceinMiles_": "=divideAndRound(2,@(1,distance),0.6215040397762585)",
"distanceinMiles": "=concat(@(1,distanceinMiles_),' ',@(1,distanceUnit))",
"distance_": "=divideAndRound(2,@(1,distance),1)",
"distance": "=concat(@(1,distance_),' ',@(1,distanceUnit))"
}
}
}
},
{
"operation": "shift",
"spec": {
"*": {
"*": {
"address": "&2[&1].&",
"city": "&2[&1].&",
"state": "&2[&1].&",
"postalCode": "&2[&1].&",
"distanceUnit": {
"mi|m|Mi|MI": { "@(2,distanceinMiles)": "&4[&3].distance" },
"*": { "@(2,distance)": "&4[&3].distance" }
}
}
}
}
}
]
哪里
第一个规范中的@(1,distanceXx)
表示遍历一个冒号(:
) (作为 Right-Hand-Side 元素)以到达
元素的原始级别 @(1,distanceXx)
,而
@(2,distanceXx)
代表遍历{
(对象开“大括号”)两次达到相同。
“locations”索引级别的属性通过[&1]和[&3][=69=组合]分别
&2和&4分别代入表示键名
"locations"
站点上的演示 http://jolt-demo.appspot.com/ :
编辑(对您上次编辑的回复):
考虑到输入
{
"data": {
"distanceUnit": "Mi",
"solrResponse": {
"header": {
"found": 32,
"retrieved": 10
},
"results": [
{
"matchScore": "08768",
"location": {
"distance": "2.7649",
"similarity": "0.342"
}
}
]
}
}
}
您可以使用以下规格
[
{
"operation": "modify-overwrite-beta",
"spec": {
"data": {
"distanceUnit": "=toLower(@(1,&))",
"solrResponse": {
"results": {
"*": {
"location": {
"dist1": "=divideAndRound(2,@(1,distance),0.6215)",
"distanceKm": "=concat(@(1,dist1), ' km')",
"dist2": "=divideAndRound(2,@(1,distance),1.0)",
"distanceMiles": "=concat(@(1,dist2), ' km')"
}
}
}
}
}
}
},
{
"operation": "shift",
"spec": {
"data": {
"*": "&1.&",
"solrResponse": {
"*": "&2.&1.&",
"results": {
"*": {
"*": "&4.&3.&2[&1].&",
"location": {
"@(4,distanceUnit)": {
"mi": { "@(2,distanceKm)": "&7.&6.&5[&4].&3.distance" },
"km": { "@(2,distanceMiles)": "&7.&6.&5[&4].distance" }
},
"similarity": "&5.&4.&3[&2].&Score"
}
}
}
}
}
}
},
{
"operation": "sort"
}
]
演示是:
我需要处理来自 SOLR 服务的响应,如下所示:
{
"data": {
"distanceUnits": "mi", //it can be "mi", "MI", "miles", "km", "KM", etc.
"solrResponse": {
"header": {
"found": 32,
"retrieved": 10,
... //there can be other things like timestamp
},
"results": [
{
"matchScore": "08768",
"indicators" [{...}],
"location": {
... //there are about hundred attributes
"distance": "2.7649" //distance always in km
"similarity": "0.342"
},
...
]
}
转换需要 return 来自 solrResponse 的所有内容几乎完好无损,除了两件事:
- similarity 需要重命名为 similarityScore 并向上移动到 matchScore 旁边。
- 如果distanceUnit指定为英里,距离需要转换为英里(即除以1.609)
- 距离值四舍五入到小数点后2位,并与distanceUnit相连。 我创建了以下规范:
[
{
"operation": "modify-overwrite-beta",
"spec": {
"data": {
"unit1": "=toLower(@(1,distanceUnit))",
"unit2": "=substring(@(1,unit1),0,1)",
"solrResponse": {
"results": {
"": {
"dist1": "=divideAndRound(2,@(1,distance),0.6215)",
"distanceMiles": "=concat(@(1,dist1), ' ', @(2,distanceUnit))",
"dist2": "=divideAndRound(2,@(1,distance),1.0)",
"distanceKm": "=concat(@(1,dist2), ' ', @(2,distanceUnit))"
}
}
}
}
}
},
{
"operation": "shift",
"spec": {
"data": {
"solrResponse": {
"header": "&1",
"response": {
"": {
"&1.similarity": "similarityScore",
"unit2": {
"m": {
"distanceMiles": "locations.distance"
},
"": {
"distanceKm": "locations.distance"
}
},
"": "&1"
}
}
}
}
}
}
]
不幸的是,它不起作用。请帮助我。
Jolt 没有 multiply
或 product
等功能,但 divide
和 divideAndRound
可用于 修改 转换规范。然后,我们将有一个条件来过滤 distanceUnit
属性的提供值是否存在于列表 (mi,m,Mi,MI
) 中,例如
[
{
"operation": "modify-overwrite-beta",
"spec": {
"*": { // this outer one represents "locations" list(if there's no other outer level list or object, otherwise replace "*" with the key name "locations")
"*": { // this one stands for "locations" list's indexes
"distanceinMiles_": "=divideAndRound(2,@(1,distance),0.6215040397762585)",
"distanceinMiles": "=concat(@(1,distanceinMiles_),' ',@(1,distanceUnit))",
"distance_": "=divideAndRound(2,@(1,distance),1)",
"distance": "=concat(@(1,distance_),' ',@(1,distanceUnit))"
}
}
}
},
{
"operation": "shift",
"spec": {
"*": {
"*": {
"address": "&2[&1].&",
"city": "&2[&1].&",
"state": "&2[&1].&",
"postalCode": "&2[&1].&",
"distanceUnit": {
"mi|m|Mi|MI": { "@(2,distanceinMiles)": "&4[&3].distance" },
"*": { "@(2,distance)": "&4[&3].distance" }
}
}
}
}
}
]
哪里
-
第一个规范中的
@(1,distanceXx)
表示遍历一个冒号(:
) (作为 Right-Hand-Side 元素)以到达 元素的原始级别@(1,distanceXx)
,而@(2,distanceXx)
代表遍历{
(对象开“大括号”)两次达到相同。“locations”索引级别的属性通过[&1]和[&3][=69=组合]分别
&2和&4分别代入表示键名
"locations"
站点上的演示 http://jolt-demo.appspot.com/ :
编辑(对您上次编辑的回复): 考虑到输入
{
"data": {
"distanceUnit": "Mi",
"solrResponse": {
"header": {
"found": 32,
"retrieved": 10
},
"results": [
{
"matchScore": "08768",
"location": {
"distance": "2.7649",
"similarity": "0.342"
}
}
]
}
}
}
您可以使用以下规格
[
{
"operation": "modify-overwrite-beta",
"spec": {
"data": {
"distanceUnit": "=toLower(@(1,&))",
"solrResponse": {
"results": {
"*": {
"location": {
"dist1": "=divideAndRound(2,@(1,distance),0.6215)",
"distanceKm": "=concat(@(1,dist1), ' km')",
"dist2": "=divideAndRound(2,@(1,distance),1.0)",
"distanceMiles": "=concat(@(1,dist2), ' km')"
}
}
}
}
}
}
},
{
"operation": "shift",
"spec": {
"data": {
"*": "&1.&",
"solrResponse": {
"*": "&2.&1.&",
"results": {
"*": {
"*": "&4.&3.&2[&1].&",
"location": {
"@(4,distanceUnit)": {
"mi": { "@(2,distanceKm)": "&7.&6.&5[&4].&3.distance" },
"km": { "@(2,distanceMiles)": "&7.&6.&5[&4].distance" }
},
"similarity": "&5.&4.&3[&2].&Score"
}
}
}
}
}
}
},
{
"operation": "sort"
}
]
演示是: