Search code examples
jsonmappingtransformationjolt

JOLT merge two arrays with common values


I have a JSON object like this:

{
   "data":{
      "list1":[
         {
            "id":"1",
            "description":"abc..",
            "title":"abc"
         },
         {
            "id":"2",
            "description":"hello..",
            "title":"hello"
         },
         {
            "id":"3",
            "description":"hello..",
            "title":"hello"
         },
         {
            "id":"4",
            "description":"hello..",
            "title":"hello"
         },
         {
            "id":"5",
            "description":"hello..",
            "title":"hello"
         },
         {
            "id":"6",
            "description":"hello..",
            "title":"hello"
         }
      ],
      "list2":[
         {
            "info":"this is list2",
            "idList":[
               "1",
               "3"
            ]
         },
         {
            "info":"this is list2",
            "idList":[
               "2",
               "4"
            ]
         }
      ]
   }
}

In the transformed JSON I want everything of list1 inside idList of list2 whenever the id matches. Like this:

{
   "res":{
      "data":[
         {
            "info":"this is list2",
            "idList":[
               {
                  "id":"1",
                  "description":"abc..",
                  "title":"abc"
               },
               {
                  "id":"3",
                  "description":"hello..",
                  "title":"hello"
               }
            ]
         },
         {
            "info":"this is list2",
            "idList":[
               {
                  "id":"2",
                  "description":"hello..",
                  "title":"hello"
               },
               {
                  "id":"4",
                  "description":"hello..",
                  "title":"hello"
               }
            ]
         }
      ]
   }
}

How can I use Jolt Spec to achieve this transformation?

[
  {
    "operation": "shift",
    "spec": {
      "data": {
        "list1": {
          "*": {
            "id": {
              "@(3,list2[&].idList)": {
                "@(4,list2[&].idList)": "res.data[&3].idList"
              }
            }
          }
        },
        "list2": {
          "*": {
            "info": "res.data[&1].info"
          }
        }
      }
    }
  }
 ]

I tried this spec to match those two lists however I don't get anything for the list1 spec. The result I get is only the info part:

{
  "res" : {
    "data" : [ {
      "info" : "this is list2"
    }, {
      "info" : "this is list2"
    } ]
  }
}

Solution

  • You can use this spec:

    [
      {
        "operation": "shift",
        "spec": {
          "*": {
            "list1": {
              "*": {
                "*": "&3.&2.@(1,id).&"
              }
            },
            "*": "&1.&"
          }
        }
      },
      {
        "operation": "shift",
        "spec": {
          "*": {
            "list2": {
              "*": {
                "*": "res.&3[&1].&",
                "idList": {
                  "*": {
                    "*": {
                      "@(5,list1.&)": "res.&6.[&4].&3"
                    }
                  }
                }
              }
            }
          }
        }
      }
    ]