【问题标题】:Can JMESPATH perform a "contains X or Y" search/filter?JMESPATH 可以执行“包含 X 或 Y”搜索/过滤吗?
【发布时间】:2020-12-20 15:38:51
【问题描述】:

是否可以使用contains 将下面的preg_match 搜索移动到JMESPATH 搜索过滤器中?我在JMESPATH tutorial 中找到了contains 的示例,但我不确定语法是否支持以某种方式使用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;
    }
  }

【问题讨论】:

    标签: php amazon-s3 sdk jmespath


    【解决方案1】:

    假设文档格式如下:

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

    (我会检查,但我手头没有 AWS 凭证,而且很难找到 S3 列表对象响应的 JSON 格式示例。)

    尝试查询:

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

    在这种情况下,Contents[].Key 仅选择键(如您的示例中所示)。管道| 用于重置投影,以便我们对整个列表进行操作,而不是单独对每个键进行操作。 [?...] 过滤列表以仅选择满足布尔条件的键。 contains 函数可以以多种方式使用,但我们在这里使用它来查看第一个参数作为字符串(@,列表中的当前项)是否包含第二个参数,即我们正在搜索的子字符串。我们将contains 函数的两种用法与或运算符|| 结合起来,这样如果其中一个 条件为真,则项目匹配。

    【讨论】:

      【解决方案2】:

      当然,or expression 确实存在于 JMESPath 中。

      但是,您甚至可以更进一步,完全放弃 for 循环并使用 functions expression 获取密钥。

      给定数据:

      {
        "Contents": [
          {
            "Key": [
              "css_foo",
              "js_bar",
              "brown_fox"
            ]
          },
          {
            "Key": [
              "js_foo",
              "css_bar",
              "lazy_dog"
            ]
          }
        ]
      }
      

      然后

      $keys = $s3_results->search(
        'Contents[].Key[?contains(@, `js_`) == `true` || contains(@, `css_`) == `true`]'
      );
      

      会给你以下二维数组(因为有两个内容):

      array(2) {
        [0] =>
        array(2) {
          [0] =>
          string(7) "css_foo"
          [1] =>
          string(6) "js_bar"
        }
        [1] =>
        array(2) {
          [0] =>
          string(6) "js_foo"
          [1] =>
          string(7) "css_bar"
        }
      }
      

      甚至更简单,因为contains 已经返回truefalse

      $keys = $s3_results->search(
        'Contents[].Key[?contains(@, `js_`) || contains(@, `css_`)]'
      );
      

      【讨论】:

        猜你喜欢
        • 2018-11-19
        • 1970-01-01
        • 2013-11-19
        • 2021-04-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多