Search code examples
jsontransformjolt

Using Jolt specs to remove all array elements if a field has one of the values


I have a JSON like this (edited)


  {
    "status": "ACTIVE",
    "users": [
      {
        "id": "1",
        "name": "Aaron",
        "accounts": [
          {
            "id": 11,
            "value": "account_11"
          },
          {
            "id": "12",
            "value": "account_12"
          }
        ]
      },
      {
        "id": "2",
        "name": "Rodney",
        "accounts": [
          {
            "id": 22,
            "value": "account_22"
          }
        ]
      },
      {
        "id": "3",
        "name": "Clayton",
        "accounts": [
          {
            "id": 33,
            "value": "account_33"
          }
        ]
      }
    ]
  }

I want to keep the users array empty when status is "PENDING", "INACTIVE" or "BLOCKED" but not of any other value of status.

e.g.

  1. for above JSON no change
  2. for following JSON

  {
    "status": "BLOCKED",
    "users": [
      {
        "id": "1",
        "name": "Aaron",
        "accounts": [
          {
            "id": 11,
            "value": "account_11"
          },
          {
            "id": "12",
            "value": "account_12"
          }
        ]
      },
      {
        "id": "2",
        "name": "Rodney",
        "accounts": [
          {
            "id": 22,
            "value": "account_22"
          }
        ]
      },
      {
        "id": "3",
        "name": "Clayton",
        "accounts": [
          {
            "id": 33,
            "value": "account_33"
          }
        ]
      }
    ]
  }

it should result in whenever the status message has one of the expected status to empty the users array.

{
  "status": "BLOCKED",
  "users": []
}

How can this be done with Jolt specs?


Solution

  • You can use the following transformation :

    [
      {
        "operation": "shift",
        "spec": {
          "*": {
            "*": "&",
            "users": {
              "@1,status": {
                "PENDING|INACTIVE|BLOCKED": {
                  "@": "&3"//returns "users":null if the matches with the literals above 
                },
                "*": {//if not one of the above listed cases 
                  "@2": "&3"
                }
              }
            }
          }
        }
      },
      {
        "operation": "modify-overwrite-beta",
        "spec": {
          "~users": [] //set [] if it is null due to the ~ character
        }
      }
    ]
    

    Edit : You just can remove the one level of wrapper in order to handle this new edited case :

    [
      {
        "operation": "shift",
        "spec": {
          // "*": {
          "*": "&",
          "users": {
            "@1,status": {
              "PENDING|INACTIVE|BLOCKED": {
                "@": "&3"
              },
              "*": {
                "@2": "&3"
              }
            }
          }
        }
        // }
      },
      {
        "operation": "modify-overwrite-beta",
        "spec": {
          "~users": []
        }
      }
    ]