在 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
时,它将把它变成一个数字字段。如果您更喜欢数字字段,可以省略链中的第二个规范。
在 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
时,它将把它变成一个数字字段。如果您更喜欢数字字段,可以省略链中的第二个规范。