jsonlistindexingjolt

How to Transform record using Json Jolt to expand lists while preserving index


I need help writing a json jolt spec to transform the following into multiple json records with the lists exploded, corresponding to their respective index.

{
  "id": "test",
  "name": "John",
  "number": [
    1,
    2,
    3
  ],
  "letter": [
    "a",
    "b",
    "c"
  ]
}

I have tried the below Spec but this will break apart only 1 list at a time and also doesn't preserve indexing. I end up with 9 records instead of 3. The mappings for the lists needs to be 1 to 1 and keep the other attributes in the record.

[
  {
    "operation": "shift",
    "spec": {
      "@": "[]"
    }
  },
  {
    "operation": "shift",
    "spec": {
      "*": {
        "number": {
          "*": {
            "@2,id": "&3.&1.id",
            "@2,name": "&3.&1.name",
            "@2,letter": "&3.&1.letter",
            "@": "&3.&1.&2"
          }
        }
      }
    }
  },
  {
    "operation": "shift",
    "spec": {
      "*": {
        "*": ""
      }
    }
  },
  {
    "operation": "shift",
    "spec": {
      "*": {
        "letter": {
          "*": {
            "@2,id": "&3.&1.id",
            "@2,name": "&3.&1.name",
            "@2,number": "&3.&1.number",
            "@": "&3.&1.&2"
          }
        }
      }
    }
  },
  {
    "operation": "shift",
    "spec": {
      "*": {
        "*": ""
      }
    }
  }
]

This is the result from running the above.

[
  {
    "id": "test",
    "name": "John",
    "number": 1,
    "letter": "a"
  },
  {
    "id": "test",
    "name": "John",
    "number": 1,
    "letter": "b"
  },
  {
    "id": "test",
    "name": "John",
    "number": 1,
    "letter": "c"
  },
  {
    "id": "test",
    "name": "John",
    "number": 2,
    "letter": "a"
  },
  {
    "id": "test",
    "name": "John",
    "number": 2,
    "letter": "b"
  },
  {
    "id": "test",
    "name": "John",
    "number": 2,
    "letter": "c"
  },
  {
    "id": "test",
    "name": "John",
    "number": 3,
    "letter": "a"
  },
  {
    "id": "test",
    "name": "John",
    "number": 3,
    "letter": "b"
  },
  {
    "id": "test",
    "name": "John",
    "number": 3,
    "letter": "c"
  }
]

The result I wish for is below:

[
  {
    "id": "test",
    "name": "John",
    "number": 1,
    "letter": "a"
  },
  {
    "id": "test",
    "name": "John",
    "number": 2,
    "letter": "b"
  },
  {
    "id": "test",
    "name": "John",
    "number": 3,
    "letter": "c"
  }
]

Hopefully what I am trying to do makes sense. Any help would be greatly appreciated.


Solution

  • You can use the following shift transformation spec :

    [
      {
        "operation": "shift",
        "spec": {
          "*": "Others.&", //the elements other than "number" and "letter"
          "number|letter": {
            // loop through all the "numbers" and "letters"
            "*": {
              "@": "main[&1].&2"
            }
          }
        }
      },
      {
        "operation": "shift",
        "spec": {
          "main": {
            "*": {
              "@2,Others": { "*": "[&1].&" }, // go two levels up the tree to grab the values of the "main" array
              "*": "[&1].&"
            }
          }
        }
      }
    ]
    

    the demo on the site Jolt Transform Demo Using v0.1.1 is :

    Jolt Transform Demo