skip to Main Content

I have an array of JSON Objects that I need to transform into a new array of JSON Objects that align with my schema. I am new to Jolt and my output is not what I need.

I tried multiple ways but not able to get my desired result.

This is my Input JSON:

{
   "totalApplication":{
      "applicationName":"MSOffice",
      "products":[
         {
            "productName":"Yearly",
            "userList":[
               {
                  "userId":"3544353",
                  "email":"[email protected]",
                  "userName":"Joe Hashashi",
                  "lastActive":"1705088660"
               },
               {
                  "userId":"3544354",
                  "email":"[email protected]",
                  "userName":"Jacob Martin",
                  "lastActive":"1705088661"
               }
            ]
         },
         {
            "productName":"Monthly",
            "userList":[
               {
                  "userId":"4545455",
                  "email":"[email protected]",
                  "userName":"Amanda Kore",
                  "lastActive":"1705088662"
               },
               {
                  "userId":"4545456",
                  "email":"[email protected]",
                  "userName":"Leo Biz",
                  "lastActive":"1705088663"
               }
            ]
         }
      ]
   }
}

This is the Jolt Spec I tried:

[
  {
    "operation": "shift",
    "spec": {
      "totalApplication": {
        "products": {
          "*": {
            "userList": {
              "*": {
                "userName": "[&3].name",
                "email": "[&3].email",
                "userId": "[&3].userId",
                "@(2,productName)": "[&3].additionalAttribute.planName",
                "lastActive": "[&3].additionalAttribute.lastActive",
                "@(4,applicationName)": "[&3].additionalAttribute.applicationName"
              }
            }
          }
        }
      }
    }
 }
]

With above mentioned specs I am getting below result:

[ {
  "additionalAttribute" : {
    "planName" : [ "Yearly", "Yearly" ],
    "applicationName" : [ "MSOffice", "MSOffice" ],
    "lastActive" : [ "1705088660", "1705088661" ]
  },
  "name" : [ "Joe Hashashi", "Jacob Martin" ],
  "email" : [ "[email protected]", "[email protected]" ],
  "userId" : [ "3544353", "3544354" ]
}, {
  "additionalAttribute" : {
    "planName" : [ "Monthly", "Monthly" ],
    "applicationName" : [ "MSOffice", "MSOffice" ],
    "lastActive" : [ "1705088662", "1705088663" ]
  },
  "name" : [ "Amanda Kore", "Leo Biz" ],
  "email" : [ "[email protected]", "[email protected]" ],
  "userId" : [ "4545455", "4545456" ]
} ]

I want this Desired Output:

[
   {
      "name":"Joe Hashashi",
      "email":"[email protected]",
      "userId":"3544353",
      "additionalAttribute":{
         "lastActive":"1705088660",
         "productName":"Yearly",
         "applicationName":"MSOffice"
      }
   },
   {
      "name":"Jacob Martin",
      "email":"[email protected]",
      "userId":"3544354",
      "additionalAttribute":{
         "lastActive":"1705088661",
         "productName":"Yearly",
         "applicationName":"MSOffice"
      }
   },
   {
      "name":"Amanda Kore",
      "email":"[email protected]",
      "userId":"4545455",
      "additionalAttribute":{
         "lastActive":"1705088662",
         "productName":"Monthly",
         "applicationName":"MSOffice"
      }
   },
   {
      "name":"Leo Biz",
      "email":"[email protected]",
      "userId":"4545456",
      "additionalAttribute":{
         "lastActive":"1705088663",
         "productName":"Monthly",
         "applicationName":"MSOffice"
      }
   }
]

Its not giving desired output. Can anyone help me with this?

2

Answers


  1. This spec should work for you, assuming that the user IDs do not repeat among different products

    [
      {
        "operation": "shift",
        "spec": {
          "totalApplication": {
            "products": {
              "*": {
                "userList": {
                  "*": {
                    "userName": "@(1,userId).name",
                    "email": "@(1,userId).email",
                    "userId": "@(1,userId).userId",
                    "lastActive": "@(1,userId).additionalAttribute.lastActive",
                    "@(2,productName)": "@(1,userId).additionalAttribute.productName",
                    "@(4,applicationName)": "@(1,userId).additionalAttribute.applicationName"
                  }
                }
              }
            }
          }
        }
      },
      {
        "operation": "shift",
        "spec": {
          "*": "[]"
        }
      },
      {
        "operation": "shift",
        "spec": {
          "*": {
            "name": "[&1].name",
            "email": "[&1].email",
            "userId": "[&1].userId",
            "additionalAttribute": "[&1].additionalAttribute"
          }
        }
      }
    ]
    

    Explanation:

    1. The first operation places the items from userList under the different userId value into a dictionary. You can apply only the first operation to see the intermediate output.
    2. The second operation replaces the dictionary with the array.
    3. The third operation puts the keys in the items of the output array in the desired order (this part is optional).

    Bonus: If the user ids may repeat among the products we have to modify the keys of the dictionary from the previous transformation. Here is the more complicated spec with the additional initial step which fulfills this potential requirement:

    [
      {
        "operation": "modify-default-beta",
        "spec": {
          "totalApplication": {
            "products": {
              "*": {
                "userList": {
                  "*": {
                    "productUserId": "=concat(@(3,productName),'-',@(1,userId))"
                  }
                }
              }
            }
          }
        }
      },
      {
        "operation": "shift",
        "spec": {
          "totalApplication": {
            "products": {
              "*": {
                "userList": {
                  "*": {
                    "userName": "@(1,productUserId).name",
                    "email": "@(1,productUserId).email",
                    "userId": "@(1,productUserId).userId",
                    "productUserId": "@(1,productUserId).productUserId",
                    "lastActive": "@(1,productUserId).additionalAttribute.lastActive",
                    "@(2,productName)": "@(1,productUserId).additionalAttribute.productName",
                    "@(4,applicationName)": "@(1,productUserId).additionalAttribute.applicationName"
                  }
                }
              }
            }
          }
        }
      },
      {
        "operation": "shift",
        "spec": {
          "*": "[]"
        }
      },
      {
        "operation": "shift",
        "spec": {
          "*": {
            "name": "[&1].name",
            "email": "[&1].email",
            "userId": "[&1].userId",
            "additionalAttribute": "[&1].additionalAttribute",
            "productUserId": null
          }
        }
      }
    ]
    
    Login or Signup to reply.
  2. You can *dynamically match the outer attributes with the attributes of the innermost objects :
    (*Since, there might exist more than one attributes at those levels, eg. 2 and 4 upper levels)

    [
      { // form independent arrays of the attributes those will be returned within the desired
        // JSON result
        "operation": "shift",
        "spec": {
          "*": {
            "*": {
              "*": {
                "userList": {
                  "*": {
                    "@2|@4": { // replicate the respective values from those levels
                      "*": "[&1].additionalAttribute.&",
                      "&2|&4": "x" // get rid of the caller arrays and keep the other elements 
                                   // by setting their values to an arbitrary literal(in this case "x")                        
                                   // unlike to upper line which's preceded by an identifier 
                    },
                    "*ame": "[&1].name", // rename this attribute
                    "*": "[&1].&",       // else case
                    "lastActive": "[&1].additionalAttribute.&" // nest this one within an object
                                                               // like the innermost ones
                  }
                }
              }
            }
          }
        }
      },
      { // reform new objects by indexes of the outer objects and of those independent arrays
        "operation": "shift",
        "spec": {
          "*": {
            "*": {
              "*": "&2_&.&1"
            },
            "additionalAttribute": {
              "*": {
                "*": "&3_&.&2.&1"
              }
            }
          }
        }
      },
      { // get rid of the object keys
        "operation": "shift",
        "spec": {
          "*": "[]"
        }
      }
    ]
    

    the demo on the site https://jolt-demo.appspot.com/ is :

    enter image description here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search