Search code examples
jsonetlapache-nifitransformationjolt

Jolt spec to apply all keys in a parent object to all objects in an array


Given an input array with objects containing various keys and an active_candidates_group key, with this key being an array of candidate objects, create a new output array where each candidate object is combined with the keys from the parent object.

It is important to note the following points:

  1. There are hundreds of keys in the parent object and it's not ideal to hard-code them.
  2. The parent object's keys' order does not matter.
  3. There should be no duplicate keys between the parent object and the candidate objects.

Input

[
  {
    "id": 123,
    "name": "foo",
    // { hundreds of other keys }
    "active_candidates_group": [
      {
        "person_id": 123,
        "person_name": "john"
        // { many fields specific to ‘candidate’ —no duplicates to parent expected }
      },
      {
        "person_id": 321,
        "person_name": "bob"
        // { many fields specific to ‘candidate’ —no duplicates to parent expected }
      }
    ]
  }
]

Desired Output

[
   {
      "id": 123,
      "name": "foo",
      // { hundreds of other keys from parent }
      "person_id": 123,
      "person_name": "john"
      // { other candidate fields }
   },
   {
      "id": 123,
      "name": "foo",
      // { hundreds of other keys from parent }
      "person_id": 321,
      "person_name": "bob"
      // { other candidate fields }
   }
]

What I tried so far:

[
  {
    "operation": "shift",
    "spec": {
      "*": { // Iterate for each object in the input array
        "active_candidates_group": { // Match 'active_candidates_group' key
          "*": { // Iterate for each object inside 'active_candidates_group'
            "@2": "&2[&1]", // Copy all keys from the parent object to the same index in the output array
            "*": "&2[&1].&" // Copy the current object to its corresponding index in the output array
          }
        }
      }
    }
  },
  {
    "operation": "remove",
    "spec": {
      "active_candidates_group": {
        "*": {
          "active_candidates_group": ""
        }
      }
    }
  }
]

Solution

  • You are so close to the solution, just distort a bit through use of "*": "[&1].&" at two different level without hardcoding the attributes individually such as

    [
      {
        "operation": "shift",
        "spec": {
          "*": {
            "active_candidates_group": {
              "*": {
                "@2": { "*": "[&1].&" }, // match at the deeper level
                "*": "[&1].&"
              }
            }
          }
        }
      },
      { // only purify for the array everyehere  
        "operation": "remove",
        "spec": {
          "*": {
            "active_candidates_group": ""
          }
        }
      }
    ]
    

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

    enter image description here