Fetch attributes for specific keys using Jolt - json

I have been trying to set key names for json array using the fields provided. I need to fetch a separate list of managers and colleagues.
Input:
{
"employeelist": [
{
"employee": "test",
"firstName": "ABC",
"lastName": "DEF"
},
{
"employee": "test1",
"firstName": "nametest",
"lastName": "namelast"
}
],
"manager": "test",
"colleague": "test1"
}
Expected Output:
{
"manager": [
{
"employee": "test",
"firstName": "ABC",
"lastName": "DEF"
}
],
"colleague": [
{
"employee": "test1",
"firstName": "nametest",
"lastName": "namelast"
}
]
}
Spec I used repeats the the complete list for both managers and colleagues.
[
{ // segregate values of the same key and form respective arrays.
"operation": "shift",
"spec": {
"employeelist": {
"*": {
"employee": {
"#(3,manager)": {
"#2": "manager.[]"
},
"#(3,colleague)": {
"#2": "colleague.[]"
}
}
}
}
}
}
]

You can use the following shift transformation spec
[
{
"operation": "shift",
"spec": {
"employeelist": {
"*": {
"#": "#1,employee" // accumulate values of "manager" and "colleague" attributes with respective "employee" values under the common arrays labeled by those values
}
},
"*": {
"$": "#(0)" // exchange the key-value pairs of the attributes "manager" and "colleague"
}
}
},
{
"operation": "shift",
"spec": {
"*": { // all newly transformed arrays
"#1,&[0]": "#(2,&[1])[]" //match values of 0th and 1st components per each array while adding a [] suffix to convert the resultant objects nested within square brackets as desired
}
}
}
]
where the first components([0]) of the newly derived arrays(test and test1) are matched with the second components([1]) within the last spec
the demo on the site http://jolt-demo.appspot.com/ is

I think this simpler jolt spec might achieve the expected output, but please note that it works only if the document that needs to be moved to the "manager" field is the first element of the array (that's why it matches the 0 index), and the document of "colleague" is the second element of the array (index 1).
[
{
"operation": "shift",
"spec": {
"employeelist": {
"0": "manager[]",
"1": "colleague[]"
}
}
}
]
Hope you find it useful!

Related

Copy a value from field to another field using Jolt while preserving the rest of the document

I'm trying to use a JOLT spec to copy the value from a JSON object to another field in the same object and keep the original document (with the new field) .
I'm trying using the shift operator, but I just can't figure out how to preserve the document.
Here's an example of the Object I'm trying to transform:
{
"contact": {
"name": "Foo",
"id": "123456",
"phone": "231-123"
},
"event": {
"name": "create",
"type": "test"
}
}
And the output should be something like this:
{
"contact": {
"name": "Foo",
"id": "123456",
"userId": "123456",
"phone": "231-123"
},
"event": {
"name": "create",
"type": "test"
}
}
In this case I want to copy the value from id to a new field named "userId"
The specs I've tried are:
[
{
"operation": "shift",
"spec": {
"*": "&",
"contact": {
"userId": "contact.id"
}
}
}
]
But that just deletes everything but the event node.
Using a modify transform would suit best for your case such as
[
{
"operation": "modify-overwrite-beta",
"spec": {
"contact": {
"userId": "#(1,id)" // goes 1 level up the tree and grabs the value of the "id" attribute
}
}
}
]
the demo on the site http://jolt-demo.appspot.com/ is :
Btw, using a shift transformation is also possible such as
[
{
"operation": "shift",
"spec": {
"contact": {
"*": "&1.&",
"#(0,id)": "&1.userId" // in this case, we have "0" instead of "1", since no need to go up the tree as identifier of value #(0,id) is on the left hand side, exactly stays at the same level with the tag "id"
},
"*": "&"
}
}
]
but obviously, the first one is simpler.

Jolt Transformation - getting last element by field Sequence

Say I have the following Json:
{
"collection": [
{
"sequence": 1,
"value": "event1"
},
{
"sequence": 2,
"value": "event2"
},
{
"sequence": 3,
"value": "event3"
}
]
}
Given that the array is not guaranteed to be sorted by "sequence", how do I extract the element that has the highest value of "sequence"?
the sub-objects of the "collection" array might be sorted by the sequence values by putting them as indexes for reformed array (call "objectWithHighestSequence") such as
[
{
"operation": "shift",
"spec": {
"collection": {
"*": "objectWithHighestSequence[#(0,sequence)]"
}
}
},
{
// only pick the last object after sorting within the shift transformation
"operation": "modify-overwrite-beta",
"spec": {
"*": "=lastElement(#(1,objectWithHighestSequence))"
}
}
]
the demo on the site http://jolt-demo.appspot.com/ is

Jolt transform array of objects to key-value

Problems
Hi, I'm using Jolt to transform e-commerce products data. For e.g:
[
{
"objectID": 1,
"string_facet": [
{
"facet_name": "eco_collection",
"facet_value": "No"
},
{
"facet_name": "performance_fabric",
"facet_value": "No"
}
]
},
{
"objectID": 2,
"string_facet": [
{
"facet_name": "activity",
"facet_value": [
"Hiking"
]
}
]
}
]
And my desired output is:
[
{
"objectID": 1,
"string_facet": {
"eco_collection": "No",
"performance_fabric": "No"
}
},
{
"objectID": 2,
"string_facet": {
"activity": [
"Hiking"
]
}
}
]
What I have done so far
I have tried this spec, but it isn't what I need:
[
{
"operation": "shift",
"spec": {
"*": {
"*": "[&1].&",
"string_facet": {
"*": {
"#facet_value": "[&1].string_facet.#facet_name"
}
}
}
}
}
]
I'm looking for an explanation in addition to solution.
Any help would be much appreciated!
You principally need "#facet_value": "#facet_name" match, start with it, then add
&2 to represent going two levels up and grabbing the key name's value(string_facet)
&3 to represent going three levels up and grabbing the indices of the main array to accumulate each attributes nested within individual object of their own.
Then, add an extra shift transformation spec to get rid of the integer key names such as
[
{
"operation": "shift",
"spec": {
"*": {
"*": "&1.&",
"string_facet": {
"*": {
"#facet_value": "&3.&2.#facet_name"
}
}
}
}
},
{
"operation": "shift",
"spec": {
"*": ""
}
}
]
the demo on the site http://jolt-demo.appspot.com/ is

Jolt Transform - Filter Array Where Fields equal

In a Jolt transform Im trying to filter an array of objects by an id, if equal to an Id on a field outside of the array.
Here is my data
{
"position": {
"positionManagerId": "123"
},
"managers": [
{
"id": "123",
"name": "John"
},
{
"id": "456",
"name": "Jack"
}
]
}
Id like to grab the manager where
managers.id == position.positonManagerId
My output would look like
{
"managerId": "123",
"managerName": "John"
}
You can apply shift transformation twice.
Combine key-value pairs under the common id values as key names within the first one so as to get a list for the searched id value( 123 in this case ) while the other pair(s) won't be lists.
Then use index values(0and1) within the second spec in order to eliminate the pair(s) without list value such as
[
{
"operation": "shift",
"spec": {
"position": {
"*": {
"$": "#(0)"
}
},
"managers": {
"*": {
"#name": "#id"
}
}
}
},
{
"operation": "shift",
"spec": {
"*": {
"0": {
"$1": "managerId"
},
"1": "managerName"
}
}
}
]

How to define a Jolt spec that will work for both array and value

Description I am working on a problem required JSON to JSON conversion, so I am using Jolt library for that. There are some nodes in my input JSON document that can come sometime as array of objects and sometime normal object. I am not able to define a Jolt spec that will work for both array of objects and single object.
Requirement If the node contains an array of objects, take the 0th element from the array and map it to the output JSON.
Jolt Spec
[
{
"operation": "cardinality",
"spec": {
"patient": {
"#": "ONE",
"*": "ONE"
}
}
},
{
"operation": "shift",
"spec": {
"patient": {
"dateOfBirth": "patient.dateOfBirth",
"firstName": "patient.firstName",
"lastName": "patient.lastName"
}
}
}
]
Input JSON (JSON Spec works fine for this input)
{
"patient": [
{
"dateOfBirth": [
"19890101",
"19890101"
],
"firstName": "Test",
"lastName": "Test"
},
{
"dateOfBirth": [
"19890101",
"19890101"
],
"firstName": "Test",
"lastName": "Test"
}
]
}
Output JSON (Getting expected output)
{
"patient" : {
"dateOfBirth" : "19890101",
"firstName" : "Test",
"lastName" : "Test"
}
}
But when the patient is not coming as an array but a single object, then the defined jolt spec is not working anymore.
Input JSON (JSON spec is not working for this input)
{
"patient": {
"dateOfBirth": [
"19890101",
"19890101"
],
"genderCode": "1",
"firstName": "Test",
"lastName": "Test"
}
}
Actual Output (Not correct)
{
"patient" : {
"dateOfBirth" : [ "19890101", "19890101" ],
"firstName" : "Test",
"lastName" : "Test"
}
}
Expected Output
{
"patient" : {
"dateOfBirth" : "19890101",
"firstName" : "Test",
"lastName" : "Test"
}
}
You can determine whether patient is an array or not through use of modify-beta transform. In this case, I've used firstElement function within that transform. Then, use conditional logic such as
[
{
"operation": "modify-overwrite-beta",
"spec": {
"isArray": ["=firstElement(#(1,patient))", "No"]
}
},
{
"operation": "shift",
"spec": {
"#(0,isArray)": {
"No": { "#(2,patient)": "patient" },
"*": { "#": "patient.&" }
}
}
},
{
"operation": "cardinality",
"spec": {
"*": {
"*": "ONE"
}
}
}
]
if the attribute "genderCode" is not needed, then add an extra remove transform such as
,
{
"operation": "remove",
"spec": {
"*": {
"genderCode": ""
}
}
}
Demo 1 :
Demo 2 :