Search code examples
jsonhtml5-videovimeovimeo-apijmespath

JMESPath how to write a query with multi-level filter?


I have been studying official documentation of JMESPath and a few other resources. However I was not successful with the following task:

my data structure is a json from vimeo api (video list): data array contains lots of objects, each object is the uploaded file that has many attributes and various options.

    "data": [
        {
          "uri": "/videos/00001",
          "name": "Video will be added.mp4",
          "description": null,
          "type": "video",
          "link": "https://vimeo.com/00001",
          "duration": 9,
          "files":[
             {
              "quality": "hd",
              "type": "video/mp4",
              "width": 1440,
              "height": 1440,
              "link": "https://player.vimeo.com/external/4443333.sd.mp4",
              "created_time": "2020-09-01T19:10:01+00:00",
              "fps": 30,
              "size": 10807854,
              "md5": "643d9f18e0a63e0630da4ad85eecc7cb",
              "public_name": "UHD 1440p",
              "size_short": "10.31MB"
            },
            {
              "quality": "sd",
              "type": "video/mp4",
              "width": 540,
              "height": 540,
              "link": "https://player.vimeo.com/external/44444444.sd.mp4",
              "created_time": "2020-09-01T19:10:01+00:00",
              "fps": 30,
              "size": 1345793,
              "md5": "cb568939bb7b276eb468d9474c1f63f6",
              "public_name": "SD 540p",
              "size_short": "1.28MB"
            },
            ... other data
          ]
        },
   ... other uploaded files
]

Filter I need to apply is that duration needs to be less than 10 and width of file needs to be 540 and the result needs to contain a link (url) from files

I have managed to get only one of structure-levels working: data[].files[?width == '540'].link

I need to extract this kind of list

[
 {
 "uri": "/videos/111111",
 "link": "https://player.vimeo.com/external/4123112312.sd.mp4"
 },
 {
 "uri": "/videos/22222",
 "link": "https://player.vimeo.com/external/1231231231.sd.mp4"
 },
...other data
]

Solution

  • Since the duration is in your data array, you will have to add this filter at that level.

    You will also have to use what is described under the section filtering and selecting nested data because you only care of one specific type of file under the files array, so, you can use the same type of query structure | [0] in order to pull only the first element of the filtered files array.

    So on your reduced exemple, the query:

    data[?duration < `10`].{ uri: uri, link: files[?width == `540`].link | [0] }
    

    Would yield the expected:

    [
      {
        "uri": "/videos/00001",
        "link": "https://player.vimeo.com/external/44444444.sd.mp4"
      }
    ]