Search code examples
jsonapache-nifijolt

How to add one object into the another objects and remove that object using jolt spec


I want to remove all the nested arrays and put values of "location" and "metarecord" in the rest json object and finally remove these object ("location" and "metarecord").

{
  "info": [
    {
      "item": "sugar",
      "price": 4,
      "state": "Alberta",
      "country": "Canada"
    },
    {
      "item": "sugar",
      "price": 4.5,
      "state": "California",
      "country": "US"
    }
  ],
  "location": {
    "continent": [
      {
        "country": "US",
        "coordinates": {
          "lang": "97º 00' W",
          "long": "38º 00' N"
        }
      },
      {
        "country": "Canada",
        "coordinates": {
          "lang": "95° 00' W",
          "long": "60° 00' N"
        }
      }
    ]
  },
  "metarecord": {
    "continent": "North America"
  }
}

the below is what i want to achieve: remove all the nested arrays and put values of "location" to their appropriate json objects using value of country (e.g if country value of an object is "Canada" then, location of "canada" should be added) and "metarecord" is to all the objects inside "info" as its general

[
  {
    "continent": "North America",
    "item": "sugar",
    "price": 4,
    "state": "Alberta",
    "country": "Canada",
    "lang": "95° 00' W",
    "long": "60° 00' N"
  },
  {
    "continent": "North America",
    "item": "sugar",
    "price": 4.5,
    "state": "California",
    "country": "US",
    "lang": "97º 00' W",
    "long": "38º 00' N"
  }
]

what i tried:

[
  {
    "operation": "shift",
    "spec": {
      "info": {
        "*": {
          "item": "[&1].item",
          "price": "[&1].price",
          "state": "[&1].state",
          "country": "[&1].country"
        }
      },
      "location": {
        "continent": {
          "@": "[&1].continent"
        }
      },
      "metarecord": {
        "continent": {
          "*": {
            "$": "[&2].&1"
          }
        }
      }
    }
  }
]

output: which is not what i want.

[
  {
    "item": "sugar",
    "price": 4,
    "state": "Alberta",
    "country": "Canada"
  },
  {
    "item": "sugar",
    "price": 4.5,
    "state": "California",
    "country": "US"
  }
]

Solution

  • You can use the following transformation

    [
      { // you can group by the countries while matching the ones taken from different arrays
        "operation": "shift",
        "spec": {
          "info": {
            "*": {
              "*": "@1,country.&",
              "@2,location.continent": { // go two levels up the tree to grab the values
                "*": {
                  "coordinates": { "*": "@2,country.&" }
                }
              },
              "@2,metarecord.continent": "@1,country.continent"
            }
          }
        }
      },
      { // pick only one from the repeating components for the arrays
        "operation": "cardinality",
        "spec": {
          "*": {
            "*": "ONE"
          }
        }
      },
      { // get rid of the object labels
        "operation": "shift",
        "spec": {
          "*": ""
        }
      }
    ]
    

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

    enter image description here