Search code examples
phpamazon-s3sdkjmespath

Can JMESPATH perform a "contains X or Y" search/filter?


Is it possible to move the preg_match search below into the JMESPATH search filter using contains? I found an example of contains in the JMESPATH tutorial, but I'm not sure if the syntax supports combining filter strings somehow using OR.

  $s3_results = $s3_client->getPaginator('ListObjects', ['Bucket' => $config['bucket']]);
  // Narrow S3 list down to files containing the strings "css_" or "js_".
  foreach ($s3_results->search('Contents[].Key') as $key) {
    if (preg_match("/(css_|js_)/", $key)) {
      $s3_keys[] = $key;
    }
  }

Solution

  • Assuming the document is in a format something like this:

    {
        "Contents": [
            {
                "Key": "some/path/css_example",
                 ...
            },
            {
                "Key": "another/path/js_example",
                 ...
            },
            {
                "Key": "blah/blah/other_example",
                 ...
            }
        ]
    }
    

    (I would check but I don't have AWS credentials to hand and it's surprisingly hard to find examples of the JSON format of an S3 list-objects response.)

    Try the query:

    Contents[].Key|[?contains(@, 'css_') || contains(@, 'js_')]
    

    In this case, Contents[].Key selects just the keys (as in your example). The pipe | is used to reset the projection so that we operate on the whole list rather than on each key separately. The [?...] filters the list to select only the keys that meet the boolean condition. The contains function can be used in several ways but we use it here to see if the first argument, as strings (@, the current item in the list) contains the second argument, the substring we're searching for. We combine two uses of the contains function with the or operator ||, so that an item matches if either condition is true.