Search code examples
jsonjolt

Jolt Transform list of nested objects to array and root item for each of them


I would like to transform following input:

[
  {
    "id": 100,
    "name": "group name",
    "variables": {
      "var1": {
        "value": "val1"
      },
      "var2": {
        "value": "val2"
      }
    }
  },
  {
    "id": 101,
    "name": "group name 2",
    "variables": {
      "var1": {
        "value": "val1"
      }
    }
  }
]

to

[
  {
    "groupId": 100,
    "groupName": "group name",
    "name": "var1",
    "value": "val1"
  },
  {
    "groupId": 100,
    "groupName": "group name",
    "name": "var2",
    "value": "val2"
  },
  {
    "groupId": 101,
    "groupName": "group name 2",
    "name": "var1",
    "value": "val1"
  }
]

I got many samples about converting array to object but can't really find sample to do the inverse, transforming nested objects into array by adding root elements for each array items. It's a kind of flatten, but everything I tried, I can't get the exact result I'm looking for.


Solution

  • You can use the following successive shift transformations specs

    [
      {
        "operation": "shift",
        "spec": {
          "*": {
            "variables": {  // loop through all the "variables"
              "*": {
                "@2,id": "&3_&1.groupId", // partition objects by outermost indexes(&3) 
                                         //  and object keys under "variable" object
                                         //  (eg.var1 and var2 -> &1)
                "@2,name": "&3_&1.groupName",
                "$": "&3_&1.name",
                "value": "&3_&1.&"
              }
            }
          }
        }
      },
      { // get rid of the object keys while reformation of the JSON as array of objects
        "operation": "shift",
        "spec": {
          "*": "[]"
        }
      }
    ]
    

    Moreover, you might try the following one to make the transformation more dynamic

    [
      {
        "operation": "shift",
        "spec": {
          "*": {
            "*": "&1.Others.group&",
            "variables": {
              "*": {
                "$": "&3.&.name",
                "*": "&3.&1.&"
              }
            }
          }
        }
      },
      {
        "operation": "shift",
        "spec": {
          "*": {
            "var*": {
              "@1,Others": { "*": "&3_&1.&" }, // go one level up the tree to grab the values from the "Others" object
              "*": "&2_&1.&"
            }
          }
        }
      },
      { // get rid of the object keys
        "operation": "shift",
        "spec": {
          "*": "[]"
        }
      }
    ]