Search code examples
jsonapache-nifijolt

JOLT - Join arrays in nested array


I am trying to achieve the following transformation. However, my solution adds undesired null values into the final array.

The transformation needs to shift names in child array for all root elements. I have created 3 cases to illustrate the problem.

Case 1

Input

{
  "root": [
    {
      "child": [
        {
          "name": "John"
        },
        {
          "name": "Frazer"
        }
      ]
    },
    {
      "child": [
        {
          "name": "Brandon"
        },
        {
          "name": "Josef"
        }
      ]
    }
  ]
}

Desired Output

{
  "NAMES": ["John,Frazer","Brandon,Josef"]
}

Case 2: One child is empty

Input

{
  "root": [
    {
      "child": []
    },
    {
      "child": [
        {
          "name": "Brandon"
        },
        {
          "name": "Josef"
        }
      ]
    }
  ]
}

Desired Output

{
   "NAMES": ["","Brandon,Josef"]
}

Case 3: All childs are empty

Input

{
  "root": [
    {
      "child": []
    },
    {
      "child": []
    }
  ]
}

Desired Output

{
   "NAMES": ["",""]
}

EDIT: root array will always have at least 1 element.

Current JOLT spec works fine except for cases where child is an empty array. It generates null values and I'm trying to specify an empty string instead (or any hardcoded string value such as "NO_NAMES")

[
  {
    "operation": "shift",
    "spec": {
      "root": {
        "*": {
          "child": {
            "*": {
              "name": "NAMES[&3]"
            }
          }
        }
      }
    }
  },
  {
    "operation": "modify-overwrite-beta",
    "spec": {
      "NAMES": {
        "*": "=trim"
      }
    }
  },
  {
    "operation": "cardinality",
    "spec": {
      "NAMES": "MANY"
    }
    },
  {
    "operation": "default",
    "spec": {
      "NAMES": []
    }
  },
  {
    "operation": "modify-overwrite-beta",
    "spec": {
      "NAMES": {
        "*": "=join(',',@0)"
      }
    }
  }
]


Solution

  • You can apply consecutive transformations modify-overwrite-beta and then shift in order to determine comma-seperated elements of the list(unless they have zero size,this case only double quotes will appear), and then concatenate them within a list such as

    [
      {
        "operation": "modify-overwrite-beta",
        "spec": {
          "root": {
            "*": {
              "child": { "*": "@(0,name)" },
              "NAMES": "=join(',',@(1,child))"
            }
          }
        }
      },
      {
        "operation": "shift",
        "spec": {
          "root": {
            "*": {
              "NAMES": "&"
            }
          }
        }
      }
    ]