Search code examples
jolt

How to add field to the nested object in jolt


for the input, I am finding out all docT's for the docNumbers in doc98 from Party.retailDemographic.partyDoc.

Along with this, I want to link the corresponding docT's to the docNumber in doc98 in the format key.docT.

for filtering out docT's I have used below technique: Pivot the elements of partyDoc by docNumber, and then only pass partyDocs thru that match doc98.docNumber

Input:

{
  "Party": {
    "retailDemographic": {
      "partyDoc": [
        {
          "docT": "01",
          "docNumber": "1234562",
          "isPrimaryDoc": false
        },
        {
          "docT": "02",
          "docNumber": "546987",
          "isPrimaryDoc": false
        }
      ]
    }
  },
  "doc98": [
    {
      "docNumber": "1234562"
    },
    {
      "docNumber": "5469871"
    },
    {
      "docNumber": "546987"
    }
  ]
}

Expected output:

{
  "response" : {
    "doc98" : [ {
      "docNumber" : "1234562",
      "key":{
        "docT" : "01"
      }
    }, {
      "docNumber" : "5469871"
    }, {
      "docNumber" : "546987",
      "key":{
        "docT" : "02"
      }
    } ],
    "Original" : {
      "item" : [ {
        "docT" : "01"
      }, {
        "docT" : "02"
      } ]
    }
  }
}

My Output:

{
  "response" : {
    "doc98" : [ {
      "docNumber" : "1234562"
    }, {
      "docNumber" : "5469871"
    }, {
      "docNumber" : "546987"
    } ],
    "Original" : {
      "item" : [ {
        "docT" : "01"
      }, {
        "docT" : "02"
      } ]
    }
  }
}

Jolt I am trying:

[
  {
    "operation": "shift",
    "spec": {
      "Party": {
        "retailDemographic": {
          "partyDoc": {
            "*": { // array index
              //
              // pivot partyDocs by docNumber 
              //
              "docNumber": {
                "*": {
                  "@2": "partyDocByNumber.&1"
                }
              }
            }
          }
        }
      },
      "doc98": "doc98" // passthru
    }
  },
  {
    // pass thru doc98 again, but also
    // use the value of "doc98.docNumber" to match 
    // one of the partyDocs to pass thru
    "operation": "shift",
    "spec": {
      "doc98": {
        // pass thru the whole doc98 object
        "@": "response.doc98",
        "*": {
          // match docNumber and it's value
          "docNumber": {
            "*": {
              // lookup a partyDoc by docNumber, and write it to
              // the output in such a way that it looks like the 
              // original input
              "@(4,partyDocByNumber.&.docT)": "response.Original.item[].docT"
            }
          }
        }
      }
    }
  }
]

Solution

  • This JOLT is really complex, so i'll try to explain it well.

    The logic is that you cannot compare two values directly in JOLT, so to get around this problem, we need to:

    • Create a dictionary (let's call it 'is') where the key is the docNumber and the value is the docT for every element in Party.
    • Create a list of every docNumber in the doc98 (let's call it not[]).
    • Assign to every element of not[] the corresponding dictionary value in 'is' (so if I have 1234, I will look for any 1234 in the upper dictionary; if there isn't one, I do nothing).
    • Finally, adjust the JSON to the required format.
        [
          {
            "operation": "shift",
            "spec": {
              "Party": {
                "retailDemographic": {
                  "partyDoc": {
                    "*": {
                      "@(0,docT)": "is.@(0,docNumber).key"
                    }
                  }
                }
              },
              "doc98": {
                "*": {
                  "#a": "is.not.@(0,docNumber)"
                }
              }
            }
          },
          {
            "operation": "modify-overwrite-beta",
            "spec": {
              "is": {
                "not": {
                  "*": "@(2,&)"
                }
              }
            }
          },
          {
            "operation": "shift",
            "spec": {
              "is": {
                "not": {
                  "*": {
                    "*": {
                      "$1": "response.doc98[].docNumber",
                      "@(1,key)": "response.doc98[#3].key.docT"
                    },
                    "@(0,key)": "Original.item[].docT"
                  }
                }
              }
            }
          }
        ]