bazaarvoice / jolt

JSON to JSON transformation library written in Java.
Apache License 2.0
1.54k stars 328 forks source link

JOLT spec for removing/skipping a JSON element based on existence of another element #1128

Open pramodgunake opened 2 years ago

pramodgunake commented 2 years ago

Hi Team,

Problem Statement: I am dealing with JSON's which includes address details ( current and permanent) of the customer. In the input JSON either the currentAddress or permanentAddress or neither of these can exist. Expectation is that in case the input JSON does not have the permanentAddress element then output json should have currentAddress element. In order to achieve this I have written the following spec which by default will insert the currentAddress element in JSON using the default operator and then attempt to skip the currentAddress element in case permanentAddress exists using the shift operator. But this doesn't seem to work.

I have the following listed input JSON and expected Output JSON

Input with permanentAddress Element:

{
    "client": {
        "mailingDetails": {
            "permanentAddress": {
                "house": "04576",
                "street": "Wilson Street",
                "addressId": "7w34df"
            },
            "citizenship": {
                "country": "USA"
            }
        }
    }
}

Expected Output:

{
  "client" : {
    "mailingDetails" : {
      "permanentAddress" : {
        "house" : "04576",
        "street" : "Wilson Street",
        "addressId" : "7w34df"
      },
      "citizenship" : {
        "country" : "USA"
      }
    }
  }
}

Actual Output:

{
  "client" : {
    "mailingDetails" : {
      "permanentAddress" : {
        "house" : "04576",
        "street" : "Wilson Street",
        "addressId" : "7w34df"
      },
      "citizenship" : {
        "country" : "USA"
      },
      "currentAddress" : {
        "addressId" : "DefaultID",
        "street" : "Default Street",
        "house" : "0001"
      }
    }
  }
}

Input without permanentAddress element

{
    "client": {
        "mailingDetails": {
            "citizenship": {
                "country": "USA"
            }
        }
    }
}

Expected Output:

{
    "client": {
        "mailingDetails": {
            "currentAddress": {
                "house": "0001",
                "street": "Default Street",
                "addressId": "DefaultID"
            },
            "citizenship": {
                "country": "USA"
            }
        }
    }
}

Actual Output:

{
  "client" : {
    "mailingDetails" : {
      "citizenship" : {
        "country" : "USA"
      },
      "currentAddress" : {
        "addressId" : "DefaultID",
        "house" : "0001",
        "street" : "Default Street"
      }
    }
  }
}

JOLT Spec being used for transformation:

[
  {
    "operation": "default",
    "spec": {
      "client": {
        "mailingDetails": {
          "currentAddress": {
            "house": "0001",
            "street": "Default Street",
            "addressId": "DefaultID"
          }
        }
      }
    }
  },
  {
    "operation": "shift",
    "spec": {
      "client": {
        "mailingDetails": {
          "permanentAddress": {
            "@1": {
              "currentAddress": null
            },
            "*": "client.mailingDetails.permanentAddress.&"
          },
          "*": "client.mailingDetails.&"
        }
      },
      "*": "&"
    }
  }
  ]

Do revert with suggestion or changes required to the above listed spec in order to achieve the expected result

ouxuyong commented 2 years ago

@pramodgunake This expression can implement your requirements, I don't know if it helps you

[{
    "operation": "modify-overwrite-beta",
    "spec": {
      "client": {
        "mailingDetails": {
          "currentAddress": {
            "house": "0001",
            "street": "Default Street",
            "addressId": "DefaultID"
          },
          "temp": ["currentAddress"]
        }
      }
    }
    },
  {
    "operation": "shift",
    "spec": {
      "client": {
        "mailingDetails": {
          "permanentAddress": {
            "@1": {
              "#permanentAddress": "client.mailingDetails.temp"
            },
            "*": "client.mailingDetails.permanentAddress.&"
          },
          "temp": {
            "@": "client.mailingDetails.temp.[#2]"
          },
          "currentAddress": "client.mailingDetails.currentAddressTemp.&",
          "citizenship": {
            "*": "client.mailingDetails.citizenship.&"
          }
        }
      }
    }
    }, {
    "operation": "shift",
    "spec": {
      "client": {
        "mailingDetails": {
          "permanentAddress": "client.mailingDetails.permanentAddress",
          "temp": {
            "0": {
              "currentAddress": {
                "@3": {
                  "currentAddressTemp": {
                    "*": "client.mailingDetails.&"
                  }
                }
              }
            }
          },
          "citizenship": {
            "*": "client.mailingDetails.citizenship.&"
          }
        }
      }
    }
    }
]