Search code examples
jsontransformetlapache-nifijolt

JSON to JSON transform using JOLTTransformJSON NiFi


I am using JOLTTransformJson Processor in Nifi.

My input is:

[
  {
    "col_name": "time",
    "data_type": "timestamp",
    "is_nullable": true
  },
  {
    "col_name": "otherData",
    "data_type": "string",
    "is_nullable": false
  }
]

I am using the below spec:

[
  {
    "operation": "shift",
    "spec": {
      "*": {
        "col_name": "name",
        "data_type": "type[0]",
        "is_nullable": {
          "true": "type[1]",
          "false": "type[1]"
        }
      }
    }
  },
  {
    "operation": "default",
    "spec": {
      "*": {
        "type[1]": "notnull"
      }
    }
  }
]

Expected Output is :

{
  "type": "record",
  "name": "table_name",
  "fields": [
    {
      "name": "time",
      "type": [
        "timestamp",
        "null"
      ]
    },
    {
      "name": "otherData",
      "type": [
        "string",
        "notnull"
      ]
    }
  ]
}

But getting the below one as the current result by combining all values in array like:

{
  "name": [
    "time",
    "otherData"
  ],
  "type": [
    [
      "timestamp",
      "int"
    ],
    null
  ]
}

Can someone please help what am I missing.


Solution

  • You can use the following first shift transformation spec through walking by the objects of the array in order to be able to repeatedly apply the techniques :

    [
      {
        "operation": "shift",
        "spec": {
          "#record": "type", // fixed values formed by using # wildcards left-hand-side
          "#table_name": "name",
          "*": {
            "col_*": "fields[#2].&(0,1)", // replicate the 1st replacement of the asterisk from the current(0th) level
            "is_nullable": { // conditional logic starts here
              "@(1,data_type)": "fields[#3].type",
              "true": {
                "#null": "fields[#4].type"
              },
              "false": {
                "#notnull": "fields[#4].type"
              }
            }
          }
        }
      },
      { //to sort the attributes within the fields array
        "operation": "sort",
        "spec": {
          "fields": ""
        }
      },
      { //to sort whole result
        "operation": "shift",
        "spec": {
          "type": "&",
          "name": "&",
          "fields": "&"
        }
      }
    ]
    

    the second and third transformation are just added to sort the attributes/arrays as desired