Home > OS >  JOLT - Move object to array if a key inside of the object exists
JOLT - Move object to array if a key inside of the object exists

Time:01-14

I want to write a JOLT definition that loops through each object in my data array, and move the object to the "found" array if the key "parent_id" is present, but otherwise, if the "parent_id" key is not present, move the entire current object to the "notfound" array.

Example input:

{
  "data": [
    {
      "ID1": "ID1",
      "ID2": "123"
    },
    {
      "parent_id": "xyz",
      "ID1": "ID1",
      "ID2": "123"
    }
  ]
}

Expected output:

{
  "notfound": [
    {
      "ID1": "ID1",
      "ID2": "123"
    }
  ],
  "found": [
    {
      "parent_id": "xyz",
      "ID1": "ID1",
      "ID2": "123"
    }
  ]
}

I've tried my hand at making the JOLT definition, but everything i've tried hasn't really worked. Any help here would be greatly appreciated!

CodePudding user response:

You can use this spec:

First, create a temp variable with the default notfound value.

So if you see any parent_id in the objects, You can add a new value found to the temp variable.

If parent_id had any value the temp value looks like this: ["found", "notfound"] and You should always pick the first element.

And in the last spec, We create the final object with parent_id or without it.

[
  {
    "operation": "modify-overwrite-beta",
    "spec": {
      "temp": "notfound"
    }
  },
  {
    "operation": "shift",
    "spec": {
      "temp": "&",
      "*": {
        "*": {
          "*": "&2[&1].&",
          "parent_id": {
            "@": "parent_id",
            "#found": "temp"
          }
        }
      }
    }
  },
  {
    "operation": "modify-overwrite-beta",
    "spec": {
      "temp": "=firstElement"
    }
  },
  {
    "operation": "shift",
    "spec": {
      "temp": {
        "found": {
          "@(3,data[0])": "&1[0]",
          "@(3,parent_id)": "&1[0].parent_id"
        },
        "notfound": {
          "@(3,data[0])": "&1[0]"
        }
      }
    }
  }
]

CodePudding user response:

You can use the following spec

[
  {// for the existence of the attribute
    "operation": "modify-overwrite-beta",
    "spec": {
      "data": {
        "*": {
          "parent_id": ["=toString", "notfound"] // If the attribute doesn't exist, then the converson doesn't occur and fill in default value as "notfound". Our aim is not string conersion, bu just an existence check through a suitable function. 
        }
      }
    }
  },
  {
    "operation": "shift",
    "spec": {
      "data": {
        "*": {
          "parent_id": {
            "notfound": {
              "@2": "&[]"
            },
            "*": { //else case, eg. found
              "@2": "found[]"
            }
          }
        }
      }
    }
  },
  {
    "operation": "remove",
    "spec": {
      "notfound": {
        "*": {
          "parent_id": ""
        }
      }
    }
  }
]

where conditional logic is used after determining the attribute with notfound case, and then get rid of that extra "notfound" parent_id.

the demo on the site enter image description here

  • Related