JOLT manipulations with extracting values from array

Viewed 37

Have JSON:

[
  {
    "id": 107110685,
    "rows": [
      {
        "date": "2022-07-05",
        "goals": []
      },
      {
        "date": "2022-07-06",
        "goals": []
      }
    ],
    "total": {
      "goals": []
    }
  },
  {
    "id": 107111205,
    "rows": [
      {
        "date": "2022-07-15",
        "goals": [
          {
            "conversion_type": "postclick",
            "cpa": "318.9"
          },
          {
            "conversion_type": "postview",
            "cpa": "79.73"
          }
        ]
      },
      {
        "date": "2022-07-16",
        "goals": [
          {
            "conversion_type": "postview",
            "cpa": "23.61"
          }
        ]
      }
    ],
    "total": {
      "goals": [
        {
          "conversion_type": "postview",
          "cpa": "42.77"
        },
        {
          "conversion_type": "postclick",
          "cpa": "363.55"
        }
      ]
    }
  }
]

I want to grab values from goals array and match it with id and `date. I'm stuck with this spec:

[
  {
    "operation": "shift",
    "spec": {
      "*": {
        "rows": {
          "*": {
            "goals": {
              "*": "[]"
            }
          }
        }
      }
    }
  }
]

I also need to add id and date fields to result to get:

[
  {
    "id": 107111205,
    "date": "2022-07-15",
    "conversion_type": "postclick",
    "cpa": "318.9"
  },
  {
    "id": 107111205,
    "date": "2022-07-15",
    "conversion_type": "postview",
    "cpa": "79.73"
  },
  {
    "id": 107111205,
    "date": "2022-07-16",
    "conversion_type": "postview",
    "cpa": "23.61"
  }
]

Also will be good if array goals is empty, then we should ignore it to avoid rows only with id and date in result. But still it's okay, if in final result will appear rows like:

{
  "id": 107110685,
  "date": "2022-07-16"
}
1 Answers

The trick is to determine the common nodes( &3 and &1 which are indices of rows and goals respectively ) while roaming within the indices of the goals array (the empty goals will automatically be eliminated as performing this) such as

[
  {
    "operation": "shift",
    "spec": {
      "*": {
        "rows": {
          "*": {
            "goals": {
              "*": {
                "@(4,id)": "&3.&1.id",
                "@(2,date)": "&3.&1.date",
                "*": "&3.&1.&"
              }
            }
          }
        }
      }
    }
  },
  {
    "operation": "shift",
    "spec": {
      "*": {
        "*": {
          "@": ""
        }
      }
    }
  }
]

Edit : The following one might be considered for such a vast input(as lately commented below) which has multiple objects with non-empty goals array in it :

[
  {
    "operation": "shift",
    "spec": {
      "*": {
        "rows": {
          "*": {
            "goals": {
              "*": {
                "@(4,id)": "&3.&1.id",
                "@(2,date)": "&3.&1.date",
                "*": "&3.&1.&"
              }
            }
          }
        }
      }
    }
  },
  {
    "operation": "shift",
    "spec": {
      "*": {
        "*": {
          "*": "[&2].&"
        }
      }
    }
  },
  {
    "operation": "shift",
    "spec": {
      "*": {
        "*": {
          "*": "[&].&1"
        }
      }
    }
  }
]
Related