【问题标题】:NiFi - Converting JSON string to valid JSONNiFi - 将 JSON 字符串转换为有效的 JSON
【发布时间】:2021-12-05 18:40:18
【问题描述】:

使用 UpdateRecord,我正在尝试将 json 字符串转换为有效的 json:

输入:

{
  "user" : "{\"id\":\"1\",\"name\":\"TEST\"}"
}

电流输出:

{
  "user":"{id=1, name=TEST}"
}

预期输出:

{
  "user": { 
      "id": "1", 
      "name": "TEST" 
  }
}

我该如何解决这个问题?使用其他处理器或脚本?能给我一个建议吗?

问候!

更新记录:

【问题讨论】:

    标签: json apache-nifi jolt


    【解决方案1】:

    您可以使用 JoltTransformJSON 处理程序(Jolt 转换库旨在将 JSON 转换为另一个 JSON)与规范

    [
      {
        "operation": "modify-overwrite-beta",
        "spec": {
          "u": "=split('\"', @(1,user))",
          "user": "=join('',@(1,u))"
        }
      },
      {
        "operation": "remove",
        "spec": {
          "u": ""
        }
      }
    ]
    

    其中\"的部分通过split被删除,然后join函数被用来组合字符串的其余部分。额外创建的辅助属性 u 在最后一步被移除。

    编辑:根据您的编辑,使用以下转换

    [
      {
        "operation": "modify-overwrite-beta",
        "spec": {
          "user": "=split('\"', @(1,user))",
          "id": "@(1,user[3])",
          "name": "@(1,user[7])"
        }
      },
      {
        "operation": "remove",
        "spec": {
          "user": ""
        }
      },
      {
        "operation": "shift",
        "spec": {
          "@": "user"
        }
      }
    ]
    

    【讨论】:

    • 谢谢,但这不是预期的结果。我刚刚更新了问题。
    • 不客气@JorgeAires,我已经编辑过了。
    • 工作就像一个魅力!我很感激。
    【解决方案2】:

    UpdateRecord 之所以这样工作,是因为它从输入记录中推断出记录的模式,并确定存在一个字符串类型的字段user

    因此,即使您尝试使用 ScriptedTransformRecord 而不是 UpdateRecord 并尝试使用 Record.setValue(fieldName,convertStringToMap(previousValue)),这会将映射转换为 String,您仍然会获得 String 类型的字段用户。 (setValue() 不会改变已有字段的类型)

    解决方法可能是丰富记录添加一个新字段,例如 user_map 类型为 Map(String,String)。

    或者,只需使用ScriptedTransformRecord 创建具有新模式的新记录,例如使用以下 groovy 脚本,其中 JsonSlurper 用于取消转义 Json

    import groovy.json.JsonSlurper
    import org.apache.nifi.serialization.SimpleRecordSchema
    import org.apache.nifi.serialization.record.MapRecord
    import org.apache.nifi.serialization.record.Record
    
    def slurper = new JsonSlurper()
    Record result = new MapRecord(new SimpleRecordSchema([]),[:]) // empty record
    record.toMap().each { k,v ->
        result.setValue(k,slurper.parseText(v as String)) // adding a field Map<String,String>
    }
    return result
    

    【讨论】:

      猜你喜欢
      • 2018-08-29
      • 2021-09-13
      • 2023-03-22
      • 1970-01-01
      • 1970-01-01
      • 2021-12-01
      • 2021-09-23
      • 1970-01-01
      • 2015-10-22
      相关资源
      最近更新 更多