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 的所有内容几乎完好无损,除了两件事:

  1. similarity 需要重命名为 similarityScore 并向上移动到 matchScore 旁边。
  2. 如果distanceUnit指定为英里,距离需要转换为英里(即除以1.609)
  3. 距离值四舍五入到小数点后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 没有 multiplyproduct 等功能,但 dividedivideAndRound 可用于 修改 转换规范。然后,我们将有一个条件来过滤 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"
  }
]

演示是: