Search code examples
jsonapache-nifijoltcamelcasing

Converting the key variable Case to Camel Case using Jolt


I am getting data from the database sources in the following format with capital keys. I want to convert keys in camel case using the JOLT transformation.

json which I may be getting does not contains fixed key value pairs. Key can vary case-to-case basis

input json

[
  {
    "LAST_UPDT_TS": "2018-05-21 07:52:06.0",
    "RTRV_TS": "2023-02-08 06:03:03.932108",
    "DOC_ID": "1-102GJ8CY",
    "PARENT_ASSET_DOC_ID": null,
    "ASSET_STATUS": "Inactive",
    "CAGE_NUM": "SUBZ6G"
  },
  {
    "LAST_UPDT_TS": "2020-09-09 22:28:25.0",
    "RTRV_TS": "2023-02-08 06:03:03.932108",
    "DOC_ID": "1-102MDPE7",
    "PARENT_ASSET_DOC_ID": null,
    "ASSET_STATUS": "Active",
    "CAGE_NUM": "012210"
  }
]

Expected output

[
  {
    "lastUpdtTs": "2018-05-21 07:52:06.0",
    "rtrvTs": "2023-02-08 06:03:03.932108",
    "docId": "1-102GJ8CY",
    "ParentAssetDocId": null,
    "AssetStatus": "Inactive",
    "CageNum": "SUBZ6G"
  },
  {
    "lastUpdtTs": "2020-09-09 22:28:25.0",
    "retrieveTimestamp": "2023-02-08 06:03:03.932108",
    "docId": "1-102MDPE7",
    "ParentAssetDocId": null,
    "AssetStatus": "Active",
    "CageNum": "012210"
  }
]

Solution

  • You can use the following spec

    [// Preparation for the next spec for assigning default "null" for null values of which the attributes won't vanish
      {
        "operation": "default",
        "spec": {
          "*": {
            "*": "null"
          }
        }
      },
      {// Exchange key-value pairs
        "operation": "shift",
        "spec": {
          "*": {
            "*": {
              "$": "&2.&1.@(0)"
            }
          }
        }
      },
      {// Split values by underscores in order to convert them to independent arrays for each attribute
        "operation": "modify-overwrite-beta",
        "spec": {
          "*": {
            "*": {
              "*": "=split('_',@(1,&))"
            }
          }
        }
      },
      {// Convert all values to lowercase letters
        "operation": "modify-overwrite-beta",
        "spec": {
          "*": {
            "*": {
              "*": {
                "*": "=toLower"
              }
            }
          }
        }
      },
      {// Enumerate each components of the arrays
        "operation": "shift",
        "spec": {
          "*": {
            "*": {
              "*": {
                "*": "&3.&2.&1.&"
              }
            }
          }
        }
      },
      {// Split those components letterwise
        "operation": "modify-overwrite-beta",
        "spec": {
          "*": {
            "*": {
              "*": {
                "*": "=split('',@(1,&))"
              }
            }
          }
        }
      },
      {// Enumerate each components of the arrays
        "operation": "shift",
        "spec": {
          "*": {
            "*": {
              "*": {
                "*": {
                  "*": "&4.&3.&2.&1.&"
                }
              }
            }
          }
        }
      },
      {
        "operation": "modify-overwrite-beta",
        "spec": {
          "*": {// Convert only the first letters of the derived pieces to uppercase letters by use of 0th(zeroth) index
            "*": {
              "*": {
                "*": {
                  "0": "=toUpper"
                }
              }
            }
          }
        }
      },
      {// Rearrange the elements to prepare to combine the pieces
        "operation": "shift",
        "spec": {
          "*": {
            "*": {
              "*": {
                "*": {
                  "*": "&4.&3.&2"
                }
              }
            }
          }
        }
      },
      {// Combine the pieces in order to get new values
        "operation": "modify-overwrite-beta",
        "spec": {
          "*": {
            "*": {
              "*": "=join('',@(1,&))"
            }
          }
        }
      },
      {
        "operation": "shift",
        "spec": {// Make values keys, while keys to values
          "*": {
            "*": {
              "*": {
                "$": "[&3].@(0)"
              }
            }
          }
        }
      },
      {
        "operation": "shift",
        "spec": {
          "*": {// get back again the real null values
            "*": {
              "null": "[&2].&1",
              "*": {
                "@1": "[&3].&2"
              }
            }
          }
        }
      }
    ]
    

    There are two immediate handicaps :

    1. Disappearing null values during key-value exchange. Used the first and the last specs to handle this issue.

    2. Identical values which would prevent separation of keys after applied key-value exchange. An extra level of deepness added to specs in order to handle this.