Apache Nifi使用执行脚本操作嵌套的json

时间:2018-11-21 11:11:57

标签: json apache nested apache-nifi

我正在寻找一种以动态方式更新给定Json的值和键的方法。 Json的交付方式始终相同(就结构而言)。唯一不同的是提供的数据量。例如,有时可能有30个嵌套,有时只有10个嵌套等。

...

"ampdata": [
                {
                    "nr": "303",
                    "code": "JGJGh4958GH",
                    "status": "AVAILABLE",
                    "ability": [ "" ],
                    "type": "wheeled",
                    "conns": [
                        {
                            "nr": "447",
                            "status": "",
                            "version": "3",
                            "format": "sckt",

                            "amp": "32",
                            "vol": "400",
                            "vpower": 22

                        }
                    ]
                }

由于Json在数据库中使用了除我以外的其他键/值,因此我需要对其进行转换。另外,如果它们与显式字符串匹配,我需要更改一些值。 因此,例如:"Code"必须重命名为"adrID",并且"sckt"应该映射到值"bike"

我尝试了一个简单的Groovy脚本来删除键或更改值。更改值没有问题,但更改密钥本身没有问题。因此,我尝试删除密钥并添加新密钥。不幸的是,我无法弄清楚如何向给定的json添加新的key:value。因此,如果可能的话,我该如何添加一对新的key:value或重命名密钥。看看我的代码示例

def flowFile = session.get()
if (!flowFile) return

try {
  flowFile = session.write(flowFile,
      { inputStream, outputStream ->
          def text = IOUtils.toString(inputStream, StandardCharsets.UTF_8)
          def obj = new JsonSlurper().parseText(text)
          def objBuilder = new JsonBuilder(obj)

          // Update ingestionDate field with today's date
          for(i in 0..obj.data.size()-1){
            obj.data[0].remove("postal_code")
            objBuilder.data[0].postal_code=5

          }
          // Output updated JSON
          def json = JsonOutput.toJson(obj)
          outputStream.write(JsonOutput.prettyPrint(json).getBytes(StandardCharsets.UTF_8))
      } as StreamCallback)
  flowFile = session.putAttribute(flowFile, "filename", flowFile.getAttribute('filename').tokenize('.')[0]+'_translated.json')
  session.transfer(flowFile, REL_SUCCESS)

} catch(Exception e) {
  log.error('Error during JSON operations', e)
  session.transfer(flowFile, REL_FAILURE)
}

1 个答案:

答案 0 :(得分:0)

...
def obj = new JsonSlurper().parse(inputStream, "UTF-8")
obj.data.each{e->
    def value = e.remove("postal_code")
    //set old value with a new key into object
    e["postalCode"] = value
}
//write to output
def builder = new JsonBuilder(obj)
outputStream.withWriter("UTF-8"){ it << builder.toPrettyString() }