在 Jolt 中如何修改输出 json 的键并从输入复制值

In Jolt how to modified the keys of out put json and copy values from input

在 Nifi 中,我想将所有输入值复制到与输入相比修改了键的输出。

输入:

{
    "test": {
    "name":"John",
    "salary":"2500.145263" 
    }
}

输出:

{
    "company": {
    "fn":"JOHN",
    "sl":"2500.14" 
    }
}

这里我想把名字大写,工资四舍五入到小数点后两位。

您可以使用 ExecuteScript 处理器进行转换并编写您自己的代码。

我为此使用了 ECMA 脚本,但也有其他选项。

    var StreamCallback = Java.type("org.apache.nifi.processor.io.StreamCallback");
    var IOUtils = Java.type("org.apache.commons.io.IOUtils");
    var StandardCharsets = Java.type("java.nio.charset.StandardCharsets");
    var flowFile = session.get();
    var obj = {};
    var strname = ""
    var strupper = ""
    var queryjson = {};
var sal 


if (flowFile != null) {
    // Create a new StreamCallback, passing in a function to define the interface method
    try {
        flowFile = session.write(flowFile,
            new StreamCallback(
                function (inputStream, outputStream) {
                    var text = IOUtils.toString(inputStream, StandardCharsets.UTF_8)

                    obj = JSON.parse(text)

                    obj.company = obj.test

                     strname = obj.test.name
                    strupper = strname.toUpperCase()
                    obj.company.fn = strupper

                    sal = parseFloat(obj.test.salary).toFixed(2)
                    obj.company.sl = sal

                    delete obj.test.name
                    delete obj.test.salary
                    delete obj.test



                    outputStream.write(JSON.stringify(obj).getBytes(StandardCharsets.UTF_8))
                }
            )
        );

        session.transfer(flowFile, REL_SUCCESS)
    }
    catch (e) {
        flowFile = session.putAttribute(flowFile, 'error', e);
        session.transfer(flowFile, REL_FAILURE)
    }
}

根据 this, there is not (yet) a pure rounding function in JOLT. However there is a divideAndRound function, try the following spec (it worked for me in the online tester 您的输入):

[
  {
    "operation": "modify-overwrite-beta",
    "spec": {
      "test": {
        "salary": "=divideAndRound(2,@(1,salary),1)"
      }
    }
  },
  {
    "operation": "modify-overwrite-beta",
    "spec": {
      "test": {
        "salary": "=toString(@(1,salary))"
      }
    }
  },
  {
    "operation": "shift",
    "spec": {
      "test": {
        "name": "company.fn",
        "salary": "company.salary"
      }
    }
    }
]

链的第一部分只是将数字除以 1,然后四舍五入到 2 位,链规范的第二部分只是将你的 salary 字段变回字符串;当您使用 divideAndRound 时,它将把它变成一个数字字段。如果您更喜欢数字字段,可以省略链中的第二个规范。