Knime JSON transformer - Adding an attribute to a JSON object - json

I have converted some columns to JSON using the columns to json node. The output from that is:
{
"Material" : 101,
"UOM" : "GRAM",
"EAN" : 7698,
"Description" : "CHALK BOX"
}
I would like to add the value of the material property as a key to each JSON object. So, my desired output is:
"101": {
"Material" : 101,
"UOM" : "GRAM",
"EAN" : 7698,
"Description" : "CHALK BOX"
}
I have tried entering the following expression in the JSON transformer node but all I get is a question mark in the new column it generates:
$Material$:{"Material":$Material$,"UOM":$UOM$,"EAN":$EAN$,"Description":$Description$}
I have also tried replacing the $Material$ with "Material" but got the same result.
How would I go about this, please?

In case you convert the Material column to String (for example with String Manipulator), you can easily configure the Columns to JSON:
As you can see the Data bound key is the important part.
The String Manipulator node configuration (string($Material$)):

I finally managed to solve this by a different method.
I split the JSON data into several columns, then used the join function to create a string in the required order. I put the resulting string through the string to JSON node to create the new JSON object.
Thanks for all your tips and comments !

Related

Split JSON into two individual JSON objects using Nifi

I have a JSON like
{
"campaign_key": 316,
"client_key": 127,
"cpn_mid_counter": "24",
"cpn_name": "Bopal",
"cpn_status": "Active",
"clt_name": "Bopal Ventures",
"clt_status": "Active"
}
Expected output
1st JSON :
{
"campaign_key": 316,
"client_key": 127,
"cpn_mid_counter": "24",
"cpn_name": "Bopal",
"cpn_status": "Active"
}
2nd JSON:
{
"clt_name": "Bopal Ventures",
"clt_status": "Active"
}
How do I acheive this by using NIFI? Thanks.
You can do what 'user' had said. The not-so-good thing about that approach is, if you number of fields are increasing, then you are required to add that many JSON Path expression attributes to EvaluateJsonPath and subsequently add that many attributes in ReplaceText.
Instead what I'm proposing is, use QueryRecord with Record Reader set to JsonTreeReader and Record Writer set to JsonRecordSetWriter. And add two dynamic relationship properties as follows:
json1 : SELECT campaign_key, client_key, cpn_mid_counter, cpn_name, cpn_status FROM FLOWFILE
json2 : SELECT clt_name, clt_status FROM FLOWFILE
This approach takes care of reading and writing the output in JSON format. Plus, if you want to add more fields, you just have add the field name in the SQL SELECT statement.
QueryRecord processor lets you execute SQL query against the FlowFile content. More details on this processor can be found here
Attaching screenshots
Karthik,
Use EvaluateJsonPath processor to get those all json Values by using its keys.
Example: $.campaign_key for gets compaign key value and $.clt_name for get clt name.
Like above one you can get all jsons.
Then use ReplaceText Processor for convert single json into two jsons.
{"Compaign_Key":${CompaignKey},...etc}
{"Clt_name":${clt_name}}
It will convert single json into two jsons.
Hope this helpful and let me know if you have issues.

How to read values from nested JSON structure in java?

How to read values from nested JSON without using any library like GSON or org.JSON?
JSON is :
{data: { "EV_TOT_AMT" : "12" , "EV_CURR" : "INR", "T_BASKET" : [{"ORDER" : "abc", "BASE" : "xyx"},{"ORDER" : "def", "BASE" : "mno"}] } }
I want to read specific values as EV_TOT_AMT , EV_CURR , ORDER.
As far as I know, Java doesn't includes a JSON parser inside it's core classes... so if you don't want to use an external library, you'll need to build your own JSON parser.
Of course, you can just search the JSON string for your desired substrings and get the values moving into the string from the next ":" to the next "," (if the first character after the ":" is not an "["). But this isn't a good approach, unless your JSON input string is going to have always the same structure... well... actually that's not a good approach, period.

Flat csv data to Json

I am trying to process a Json data in Java. I have the data in below format (it is nested data structure with arrays etc.)
person.name,person.friend[0],person.friend[1],person.address.city,person.address.country
1,x,y,kolkata,india
2,a,b,london,uk
The first line is header denoting the nested object hierarchy. I want a json in below format,
{
"data" : [
{
"name" : "1",
"friend" : ["x","y"],
"address" : { "city" : "kolkata", "country" : "india" }
},
{
"name" : "2",
"friend" : ["a","b"],
"address" : { "city" : "london", "country" : "uk" }
} ]
}
The object structure is dynamic and I dont know the columns or header in advance, i.e. I can not use any predefined POJO to get populated with the data. In this example, it "Person" object but it may be any object structure.
I have gone through Jackson or Gson API, but none seems to fulfill this requirement. Is there any API that can help? or any other wayout?
Thanks
You need to do it in 2 steps.
First, you have to parse your CSV. I recommend superCSV. Parsing CSV may be fancy sometimes, so I really recommend you to use a library for that.
Second, you can serialize into JSON. Then you can use GSON, jackson, flexjson, whatever.
After a long Google...I found that the only option is to represent a collection based object structure in flat file is repeated rows,
person.name,person.friends,person.address.city,person.address.country
1,x,kolkata,india
1,y,kolkata,india
2,a,london,uk
2,b,london,uk
where the non-array elements repeats. We need to form a json from this, then need to filter or club the same object by its ID (here person.name)

Can I get MOXy to not output an element when generating json?

An instance of my JAXB Object model contains an element that I want output when I generate Xml for the instance but not when I generate json
i.e I want
<release-group>
<type>Album</type>
<title>Fred</title>
</release-group>
and
"release-group" : {
"title" : "fred",
},
but have
"release-group" : {
"type" : "Album",
"title" : "fred"
},
Can I do this using the oxml.xml mapping file
This answer shows how I can do it for attributes using the transient keyword, Can I get MOXy to not output an attribute when generating json? but I cannot get that to work for an element.
Sorry problem solved, a bit of confusion on my part.
The example I gave above didn't actually match the true situation accurately, type was actually output as an attribute for Xml, but use of transient didnt work because it had been renamed in the JAXB
#XmlAttribute(name = "target-type", required = true)
#XmlSchemaType(name = "anyURI")
protected String targetType;
So adding
<java-type name="ReleaseGroup">
<java-attributes>
<xml-transient java-attribute="targetType"/>
</java-attributes>
</java-type>
worked, previously I was incorrectly doing
<java-type name="ReleaseGroup">
<java-attributes>
<xml-transient java-attribute="target-type"/>
</java-attributes>
</java-type>

problem in accessing json parameters

I have to use json file like this:
({"weather":{"city":"Paris", "country":"France"}})
I write a JsonStore as:
root : "weather",
fields : ['city', 'country']
I cant access them like:
myStore.on('load', function(store, records, options) {
alert(records[0].get('city'));
}
but how can I access them because my json file doesn't have bracket
another case is when I want to access somthing like this:
({"data":{"weather":[{ "city" : "Paris", "country" : [{"value" : "France"}] }]}})
I define root as "data.weather"
fields:['city','country']
but I cant access value of country
please describe json file parsing or is there a way to load json file as plain/text?
I'm not familiar with extjs but I'll give this a shot since it doesn't seem to be very specific to the framework.
You can't index into records because you don't have an array in your JSON. I'd imagine if you used records.get('city'), you'd get Paris.