Setting value as object in JSON-LD expansion - json

I try to convert JSON to JSON-LD and was wondering if I could use JSON-LD expansion algorithm for creating my converter. Then I could just specify my schema as a context and run the expansion algorithm for doing the conversion. Problem is that I cannot figure out how to define new value objects in context so that the expansion algorithm would work.
Let's say I have this:
{
"timestamp": "2016-01-08T11:01:38Z"
}
and I want to get this:
{
"prefix:time": {"prefix:start": "2016-01-08T11:01:38Z"}
}
I have tried it using the JSON-LD playground with something like this:
{
"#context": {
"timestamp": {
"#id": "prefix:time",
"#value": {"prefix:start": "#value"}
}
},
"timestamp": "2016-01-08T11:01:38Z"
}
But the expanded result looks like this:
[
{
"prefix:time": [
{
"#value": "2016-01-08T11:01:38Z"
}
]
}
]
Is there any way to use the JSON-LD expansion (or other) algorithm to replace the value with a new JSON object?

This Jolt transform does the transform you described.
[
{
"operation": "shift",
"spec": {
"timestamp": "prefix:time.prefix:start"
}
}
]
You can try it out at http://jolt-demo.appspot.com/

Related

Update Json-Attributes in Apache-Nifi: Jolt

I'm a newbie on Apache Nifi and have the following Problem: I would like to transform a json file as follows:
From:
{
"Property1": "x1",
"Property2": "Tag_**2ABC**",
"Property3": "x3",
"Property4": "x4"
}
to:
{
"**2ABC**_Property1": "x1",
"**2ABC**_Property3": "x3",
"**2ABC**_Property4": "x4"
},
it means: taking the value from a certain Attribute to update all other attributes.
I could find examples using JoltTransformer-Processor that works well when the update is only adding a string. But not for my case
What I've done so far: I have set each Attribute using evaluateJSONPath processor. But I just tried quite a lot of possibilities to use the update Attribute processor to do it without success. All my possible tests looked like (within UpdateAttribute):
Property1 --> ${'Property2':substring(4,6)}"_"${'Property1'}
Using Jolt:
[
{"operation": "modify-overwrite-beta",
"spec": {
"Property1": "${'Property2':substring(4,6)}_${'Property1'}"
}
}
]
Which point am I missing here? Thanks in advance!
I don't know about Nifi, but here is how you can do it in Jolt.
Spec
[
{
"operation": "shift",
"spec": {
// match Property2
"Property2": {
"Tag_*": { // capture the nasty "**2ABC**" part to reference later
// go back up the tree to the root
"#2": {
// match and ignore Property2
"Property2": null,
//
// match Property* and use it and the captured
// "prefix" to create the output key
// &(2,1) references the Tag_*, and pull off the "**2ABC**" part
"Property*": "&(2,1)_&"
}
}
}
}
}
]

Jolt Transform using two 2 values to create a new key/value pair

I have a JSON input that I am transform using JOLT shift. My problem is I want to use the value of an input key, as a new key in the output data, and in parallel add another value into that new outputted key. Here is my input:
"Description": {
"Name": "John",
"KeyNameId": "John123",
"Description": "John's description"
}
And I want my output to be:
"Description": {
"John123": "John's description"
}
Anyway to do this without using two shift operations?
Or with two shifts if one isn't possible?
Yes, it can be done in a single shift using the "#(Number,words)" operator.
Input - slightly modified for clarity
{
"Top": {
"Name": "John",
"KeyNameId": "John123",
"Description": "John's description"
}
}
Spec
[
{
"operation": "shift",
"spec": {
"Top": {
// match the key "Description" and copy it's value to the Output.
// The Output path being defined by #(1,KeyNameId), which means
// go back up the tree 2 levels (0,1) and lookup the value of
// "KeyNameId"
"Description": "#(1,KeyNameId)"
}
}
}
]
To be more precise,
[
{
"operation": "shift",
"spec": {
"Description": {
"#Description": "Description.#KeyNameId"
}
}
}
]

Json to Json transforms using json surfer or Jolt with varying attribute name

I had a problem where I had json that looked like this--where the "key" in the json is variable:
{
"rpt":{
"tests": [
{"kerryA":[1,2,3,4]},
{"wallB":[1,2]},
{"MaryA":[1,2,3]}
]
}
}
I wanted it to look like this:
{
"rpt": {
"tests": [
{
"id":"kerryA",
"testTaken":[1,2,3,4]
},
{
"id":"wallB",
"testTaken":[1,2]
},
{
"name":"MaryA",
"testTaken":[1,2,3]
}
]
}
}
I looked at JsonSurfer and Jolt but they didn't seem to support the transform I was looking for. I solved it by rewriting the ObjectNode by recursing through the json with Jackson. While this wasn't bad, I feel like the json to json tranasformation that I looked at did not support the variable "key" well... Other than rewriting and recursing like I did, is there a more elegant transformation solution?
You can achieve it using JOLT with shift operation:
The spec would be:
[{
"operation": "shift",
"spec": {
"rpt": {
"tests" : {
"*": {
"*": {
"$": "rpt.tests[&2].id",
"#": "rpt.tests[&2].testTaken"
}
}
}
}
}
}
]
Take into account that Shiftr treats JSON arrays in the input data as Maps with numeric keys. That is why the double "*" and why rpt.tests[&2].id refers to the element of the array.
You can get more information about the shift operation at: https://github.com/bazaarvoice/jolt/blob/master/jolt-core/src/main/java/com/bazaarvoice/jolt/Shiftr.java
An example to process it in Java would be:
Object inputJSON = JsonUtils.classpathToObject("/input.json");
List<Object> chainrSpecJSON = JsonUtils.classpathToList("/spec.json");
Chainr chainr = Chainr.fromSpec(chainrSpecJSON);
Object transformedOutput = chainr.transform(inputJSON);
System.out.println(JsonUtils.toPrettyJsonString(transformedOutput));
Where input.json is a file in the classpath with your entry data and spec.json is a file with the before code.

Is it possible to concatenate the values of JSON attributes using JOLT?

I am wondering if there is any way to concatenate the values of JSON attributes into one new attribute using JOLT transformation.
For example, I have the following JSON:
{
"name": "Mary",
"Year Joined": "2017",
"Gender": "Female"
}
and I would like it to be transformed into this:
{
"new": "Mary_2017_Female"
}
Is it possible to do this using JOLT or are there other alternative ways to do it?
Yes, but it uses a "beta" transform that may change in the future.
http://jolt-demo.appspot.com/#modify-stringConcat
Expanding #Milo answer (not a fan of links outside SO)
Yes, you can achieve this using modify-overwrite-beta transform
The specification for your example would look like:
[
{
"operation": "modify-overwrite-beta",
"spec": {
"new": "=concat(#(1,name),'_',#(1,Year Joined),'_',#(1,Gender))"
}
}
]

Usage of special character "#" in JOLT template

Please help me in writing the jolt spec to get the expected output with special character "#" as shown below. When I place "#FirstName":"Names.FirstName" in the spec it is not working. Please help in resolving this.
JSON Input:
{
"FirstName": "First"
}
Jolt Spec:
[
{
"operation": "shift",
"spec": {
"FirstName": "Names.FirstName"
}
}
]
Expected Output:
{
"Names" : {
"#FirstName" : "First"
}
}
Updated : As of Jolt version 0.0.21, the "shift" transform now allows special characters to escaped.
This Spec will allow "#FirstName" to be a key in the output.
[
{
"operation": "shift",
"spec": {
"FirstName": "Names.\\#FirstName"
}
}
]