Search code examples
jsonjolt

JOLT spec to perform group by ID and condition check on nested json


Please help me to provide a JOLT spec for the below input JSON. Tried multiple approaches but still not working. There is a condition check on the risk attribute; if the risk is "0," then the risk level is low. If it is "1", then it is High; if it is null, then it should be null. Only I got a solution, but for null value, the output JSON attribute is not showing.

Input JSON :

[
  {
    "id": "12",
    "name": "Manu",
    "age": 26,
    "location": "New York",
    "risk": "0"
  },
  {
    "id": "12",
    "name": "Manju",
    "age": 29,
    "location": "New York",
    "risk": null
  },
  {
    "id": "123",
    "name": "sanju",
    "age": 24,
    "location": "New York city",
    "risk": "1"
  },
  {
    "id": "1234",
    "name": "Ramesh",
    "age": 23,
    "location": "India",
    "risk": null
  }
]

Expected JSON :

[
  {
    "id": "12",
    "location": "New York",
    "user": [
      {
        "name": "Manu",
        "age": 26,
        "riskLevel": "Low"
      },
      {
        "name": "Manju",
        "age": 29,
        "riskLevel": null
      }
    ]
  },
  {
    "id": "123",
    "location": "New York city",
    "user": [
      {
        "name": "sanju",
        "age": 24,
        "riskLevel": "High"
      }
    ]
  },
  {
    "id": "123",
    "location": "India",
    "user": [
      {
        "name": "Ramesh",
        "age": 23,
        "riskLevel": null
      }
    ]
  }
]

Solution

  • You can use the following transformation

    [ //set an arbitrary value(say "NUll") to a null valued "risk"
      {
        "operation": "modify-overwrite-beta",
        "spec": {
          "*": {
            "~risk": "NUll" //occures whnever risk is null due to the ~ operator 
          }
        }
      },
      {
        "operation": "shift",
        "spec": {
          "*": {
            "*": "@1,id.&[]", //the attributes other than the ones below
            "name|age": "@1,id.&1.&",
            "risk": {
              "1": { "#High": "@3,id.&3.riskLevel" }, //hardcode by # operator
              "0": { "#Low": "@3,id.&3.riskLevel" },
              "NUll": { "@": "@3,id.&3.riskLevel" }
            }
          }
        }
      },
      {//nest some attributes with array "user" while pick the first occurence fron the newly formed "id" and "location" arrays
        "operation": "shift",
        "spec": {
          "*": {
            "id|location": {
              "0": "&2.&1"
            },
            "*": "&1.user[]"
          }
        }
      },
      { //get rid of the wrapper keys of "id" values
        "operation": "shift",
        "spec": {
          "*": "[]"
        }
      }
    ]