jmespath

Get latest element with certain prefix in JMESPath


I have a JSON input like that:

{
  "details": [
    {
      "file": [
        "xxx-abc"
      ],
      "filePushedAt": "2021-10-25T09:31:39+02:00"
    },
    {
      "file": [
        "xxx-dfg"
      ],
      "filePushedAt": "2021-11-08T16:24:05+01:00"
    },
    {
      "file": [
        "hij"
      ],
      "filePushedAt": "2022-01-26T15:24:17+01:00"
    },
    {
      "file": [
        "xxx-klm"
      ],
      "filePushedAt": "2022-01-27T15:24:18+01:00"
    },
    {
      "file": [
        "opr"
      ],
      "filePushedAt": "2021-11-28T09:31:39+02:00"
    }
  ]
}

Using JMESPath I need to get the latest file (latest filePushedAt) which consists xxx prefix in file array.

I am able to extract files names in order by using

sort_by(details,& filePushedAt)[*].file[*] 

but cannot complete the task. I'm wondering if it is even possible without jq?


Solution

  • In order to filter the file arrays nested in the details one, you need to filter at the details level.
    You will need the starts_with function in order to filter all elements of the file arrays for the prefix xxx.

    So, knowing all this, we have the query:

    details[?file[?starts_with(@,`xxx`)]]
    

    That gives us the filtered array:

    [
      {
        "file": [
          "xxx-abc"
        ],
        "filePushedAt": "2021-10-25T09:31:39+02:00"
      },
      {
        "file": [
          "xxx-dfg"
        ],
        "filePushedAt": "2021-11-08T16:24:05+01:00"
      },
      {
        "file": [
          "xxx-klm"
        ],
        "filePushedAt": "2022-01-27T15:24:18+01:00"
      }
    ]
    

    Now, to fulfil you requirement, you still need, a sort_by, a reverse, because sort_by does not have an option to sort ascending or descending, and to select the first item of the array, with [0].

    So, now, given the query

    reverse(sort_by(details[?file[?starts_with(@,`xxx`)]], &filePushedAt))[0]
    

    You do have the object you were looking for:

    {
      "file": [
        "xxx-klm"
      ],
      "filePushedAt": "2022-01-27T15:24:18+01:00"
    }