Search code examples
jsonapache-nifijolt

Dynamic Jolt spec to handle when one nested array is present and and if nested array is not present


Dynamic Jolt spec to handle when one nested array is present and and if nested array is not present

My jolt spec is working perfectly fine if we receive the nested array, but if they send a JSON without the nested array, its failing. Is there a way to make it work for both cases

Hi,

Here is my input JSON 1

{
  "time": "2023-02-21T14:24:34.966Z",
  "itemId": "G20864_270",
  "unitOfMeasure": "PIECE",
  "futureAvailability": [
    {
      "availableQuantity": 200,
      "ETA": "2023-03-01T00:00:00.000Z"
    },
    {
      "availableQuantity": 201,
      "ETA": "2023-03-01T00:00:00.000Z"
    }
  ]
}

Input 2

{
  "time": "2023-02-22T09:13:52.168Z",
  "itemId": "G20824_510",
  "unitOfMeasure": "PIECE"
}

Jolt Spec I m using

[
  {
    "operation": "shift",
    "spec": {
      "futureAvailability": {
        "*": {
          "@(2,time)": "[&1].time",
          "@(2,itemId)": "[&1].itemId",
          "@(2,unitOfMeasure)": "[&1].unitOfMeasure",
          "ETA": "[&1].ETA",
          "availableQuantity": "[&1].availableQuantity"
        }
      }
    }
  }
]

Output

[
  {
    "time": "2023-02-21T14:24:34.966Z",
    "itemId": "G20864_270",
    "unitOfMeasure": "PIECE",
    "ETA": "2023-03-01T00:00:00.000Z",
    "availableQuantity": 200
  },
  {
    "time": "2023-02-21T14:24:34.966Z",
    "itemId": "G20864_270",
    "unitOfMeasure": "PIECE",
    "ETA": "2023-03-01T00:00:00.000Z",
    "availableQuantity": 201
  }
]

Solution

  • You can use the following spec with the cardinality transformation added ,which is for the case when the futureAvailability array exists, since, in this case, those attributes will repeatedly return

    [
      {
        "operation": "shift",
        "spec": {
          "*": {
            "@": "[0].&"
          },
          "futureAvailability": {
            "*": {
              "@(2,time)": "[&1].time",
              "@(2,itemId)": "[&1].itemId",
              "@(2,unitOfMeasure)": "[&1].unitOfMeasure",
              "*": "[&1].&"
            }
          }
        }
      },
      {
        "operation": "cardinality",
        "spec": {
          "*": {
            "time": "ONE",
            "itemId": "ONE",
            "unitOfMeasure": "ONE"
          }
        }
      }
    ]
    

    which returns

    [
      {
        "time": "2023-02-21T14:24:34.966Z",
        "itemId": "G20864_270",
        "unitOfMeasure": "PIECE"
      }
    ]
    

    whenever futureAvailability doesn't exists. If you need exactly to return the original, eg

    {
      "time": "2023-02-21T14:24:34.966Z",
      "itemId": "G20864_270",
      "unitOfMeasure": "PIECE"
    }
    

    then get rid of the qualifier [0].