Search code examples
jsonjolt

How to flattend json object that has an array as a value with JOLT transformation


I have an JSON object in following format:

{
  "$type": "api.something, api.somethingElse",
  "fromApi": {
    "$type": "api.something, api.somethingElse",
    "Id": "d1537a72-2e46-29c0-b119-2bac07857ka9",
    "ItemId": "d1537a72-2e46-29c0-b119-2bac07869t8",
    "Amount": 50,
    "Increased": 10,
    "Type": "increasment",
    "SourceData": "{\"isIncreasment\":true,\"ItemId\":\"d1258672-3592-29c0-b119-2bac07857ka9\",\"testID\":105,\"ListId\":18576}",
    "Date": "2023-06-12T13:47:57.66"
  }
}

and with JOLT transformation I want to get it in flatten format, like this:

{
  "type" : "api.something, api.somethingElse",
  "Id" : "d1537a72-2e46-29c0-b119-2bac07857ka9",
  "ItemId" : "a1537a72-2e46-29c0-b119-2bac07869t8",
  "Amount" : 50,
  "Increased" : 10,
  "Type" : "increasment",
  "isIncreasment" : "true",
  "ItemId" : "d1258672-3592-29c0-b119-2bac07857ka9",
  "testID" : 105,
  "ListId" : 18576,
  "Date": "2023-06-15T13:47:57.66"
}

Is this possible and how to do it?


Solution

  • There's no direct replacement function, but might be simulated through use of successive split and join functions within modify transformation(s) such as

    [
      {
        "operation": "modify-overwrite-beta",
        "spec": {
          "fromApi": {
            "sd0": "=split('\"',@(1,SourceData))",
            "sd1": "=join('',@(1,sd0))",
            "sd2": "=split('\\{',@(1,sd1))",
            "sd3": "=join('',@(1,sd2))",
            "sd4": "=split('\\}',@(1,sd3))",
            "sd5": "=join('',@(1,sd4))",
            "SourceData": "=split(',',@(1,sd5))"
          }
        }
      },
      {
        "operation": "shift",
        "spec": {
          "fromApi": {
            "\\$type": "others.type",
            "ItemId": "others.ItemId_old", // need to rename, otherwise will yield an array with 
                                           // two components as an object might not have two attributes 
                                           // with the common names
            "*": "others.&",
            "sd*":"sd.&",
            "SourceData": {
              "*": {
                "*:*": { // separate the keys and values
                  "#k": "&2.&(1,1)", // piece extracted from "*:*" representation after reaching 1 upper level, till ":", eg. 1st asterisk
                  "#v": "&2.&(1,2)"  // piece extracted from "*:*" representation after reaching 1 upper level, till ":", eg. 2nd asterisk
                }
              }
            }
          }
        }
      },
      {
        "operation": "shift",
        "spec": {
          "*": {
            "*": {
              "$": "&2.@0" // exchange keys vs. values
            }
          },
          "others": {
            "*": "&1.&"
          },
          "sd*": {
            "*": "&1.&"
          }
        }
      },
      {
        "operation": "shift",
        "spec": {
          "others": {
            "*": "&"
          },
          "*": {
            "@v": "@k" // match derived keys and values as pairs
          }
        }
      }
    ]