Home > front end >  How to define a Jolt spec that will work for both array and value
How to define a Jolt spec that will work for both array and value

Time:12-08

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"
  }
}

CodePudding user response:

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 : enter image description here

Demo 2 : enter image description here

  • Related