Search code examples
arraysjsontransformationjolt

JOLT Flatten Array


I am using JOLT to transform a JSON array to JSON array but unable to transform like expected. I have the following input json (simplified):

{
  "object": {
    "settings": [
      {
        "key": {
          "id": 1
        },
        "rec": {
          "value": "value 1"
        }
      },
      {
        "key": {
          "id": 2
        },
        "rec": {
          "value": "value 2"
        }
      },
      {
        "key": {
          "id": 3
        },
        "rec": {
          "value": "value 3"
        }
      }
    ],
    "customer": [
      {
        "key": {
          "id": 4
        },
        "rec": {
          "address": "some address"
        }
      }
    ]
  },
  "date": "2024"
}

and I'd like to transform all object's records to flatten array like this

[ {
  "date" : "2024",
  "id" : 4,
  "address" : "some address"
}, {
  "date" : "2024",
  "id" : 1,
  "value" : "value 1"
}, {
  "date" : "2024",
  "id" : 2,
  "value" : "value 2"
}, {
  "date" : "2024",
  "id" : 3,
  "value" : "value 3"
} ]

My latest attempt is the following jolt:

[
  {
    "operation": "shift",
    "spec": {
      "object": {
        "customer": {
          "*": {
            "@3,date": "[&1].[0].date",
            "key": {
              "id": "[&2].[0].id"
            },
            "rec": {
              "address": "[&2].[0].address"
            }
          }
        },
        "settings": {
          "*": {
            "@3,date": "[&1].[1].date",
            "key": {
              "id": "[&2].[1].id"
            },
            "rec": {
              "value": "[&2].[1].value"
            }
          }
        }
      }
    }
  },
  {
    "operation": "shift",
    "spec": {
      "*": {
        "@0": {
          "*": "[&1]"
        }
      }
    }
  }
]

But the result is:

[ [ {
  "date" : "2024",
  "id" : 4,
  "address" : "some address"
}, {
  "date" : "2024",
  "id" : 1,
  "value" : "value 1"
} ], {
  "date" : "2024",
  "id" : 2,
  "value" : "value 2"
}, {
  "date" : "2024",
  "id" : 3,
  "value" : "value 3"
} ]

Please help to fix it. Thanks in advance.


Solution

  • Good attempt! Rather just try to orchestrate the * (in order to represent common keys) vs &(to represent layers and values) wildcards such as

    [
      { // form separated objects as desired
        "operation": "shift",
        "spec": {
          "object": {
            "settings|customer": {//they both use the common depth level for the attributes
              "*": {
                "@3,date": "&2_&1.date",
                "*": {
                  "*": "&3_&2.&"
                }
              }
            }
          }
        }
      },
      { // get rid of the object keys and return array of objects with no key
        "operation": "shift",
        "spec": {
          "*": "[]"
        }
      }
    ]