Search code examples
jsonjolt

In Jolt,, how do we use a field value inside an array of objects to refer to an outside key?


I would need to perform shift operation and loop through 'userList' to assign 'address', 'metadata', etc to form a new structure. While doing so, I need to refer to 'id' of each objects and extract the user details from the object "USER_DETAILS_id" that is outside the array.

I am not able to use the value of 'id' while looping through the array to extract the user details from "USER_DETAILS_id". I tried using "&" inside "id" but that would not work.

My input:

{
    "otherList": [
        {
            "id": "def",
            "displayDetail": "Text here."
        },
        {
            "id": "abc",
            "displayDetail": "Text"
        }
    ],
    "userList": [
        {
            "id": "FIRST-d87c-11ed-a612",
            "address": "123 Elm street",
            "metadata": {
                "userInput": "",
                "userOutput": ""
            },
            "subComponentId": "12.1"
        },
        {
            "id": "SECOND-d87c-11ed-a612",
            "accessFullName": "456 Little Elm street",
            "metadata": {
                "userInput": "",
                "userOutput": ""
            },
            "subComponentId": "12.2"
        }
    ],
    "USER_DETAILS_FIRST-d87c-11ed-a612": {
        "id": "FIRST-d87c-11ed-a612",
        "textValue": "Text value for first user.",
        "detail": "Comp|Boorgu,Johny|04-11-23"
    },
    "USER_DETAILS_SECOND-d87c-11ed-a612": {
        "id": "SECOND-d87c-11ed-a612",
        "textValue": "Text value for second user.",
        "detail": "Limit|Kaur,Rajesh|04-11-23"
    }
}

So my output could be something like:

{
    "components": [
        {
            "componentId": "1",
            "isEditable": true,
            "type": "other",
            "subComponent": [
                {
                    "subComponentId": "1.1",
                    "otherId": "def",
                    "inputUI": "",
                    "displayDetail": "Text here."
                },
                {
                    "subComponentId": "1.2",
                    "otherId": "abc",
                    "inputUI": "",
                    "displayDetail": "Text"
                }
            ]
        },
        {
            "componentId": "2",
            "isEditable": true,
            "type": "user",
            "subComponent": [
                {
                    "subComponentId": "2.1",
                    "userId": "FIRST-d87c-11ed-a612",
                    "address": "123 Elm street",
                    "inputUI": "Comp|Boorgu,Johny|04-11-23",
                    "displayDetail": "Text value for second user."
                },
                {
                    "subComponentId": "2.2",
                    "userId": "SECOND-d87c-11ed-a612",
                    "address": "456 Little Elm street",
                    "inputUI": "Limit|Kaur,Rajesh|04-11-23",
                    "displayDetail": "Text value for first user."
                }
            ]
        }
    ]
}

Solution

  • The trick is to qualify the values(on the RHS) by @1,id notation such as

    [
      {
        "operation": "shift",
        "spec": {
          "userList": {
            "*": { // renaming the attributes occur in the next two lines
              "id": "@1,id.userId",
              "address|accessFullName": "@1,id.address",
              "subComponentId": "@1,id.&"
            }
          },
          "*": { // other stuff than the "userList" array
            "detail": "@1,id.inputUI",
            "textValue": "@1,id.displayDetail"
          }
        }
      },
      { // get rid of the object keys
        "operation": "shift",
        "spec": {
          "*": {
            "@": ""
          }
        }
      }
    ]
    

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

    enter image description here