本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
AWS SDK for PHP 版本 3 中的 JMESPath 表达式
JMESPathAws\ResultInterface
和 Aws\ResultPaginator
公开 JMESPath 搜索。
您可以在浏览器中通过在线 JMESPath 示例
AWS CLI
从结果中提取数据
Aws\ResultInterface
接口的 search($expression)
方法可根据 JMESPath 表达式从结果模型中提取数据。使用 JMESPath 表达式从结果对象中查询数据,有助于删除样板文件条件代码,并且更精确地表达提取出的数据。
为演示其工作方式,我们来看下面的默认 JSON 输出,它描述了连接到不同 Amazon EC2 实例的两个 Amazon Elastic Block Store (Amazon EBS) 卷。
$result = $ec2Client->describeVolumes(); // Output the result data as JSON (just so we can clearly visualize it) echo json_encode($result->toArray(), JSON_PRETTY_PRINT);
{ "Volumes": [ { "AvailabilityZone": "us-west-2a", "Attachments": [ { "AttachTime": "2013-09-17T00:55:03.000Z", "InstanceId": "i-a071c394", "VolumeId": "vol-e11a5288", "State": "attached", "DeleteOnTermination": true, "Device": "/dev/sda1" } ], "VolumeType": "standard", "VolumeId": "vol-e11a5288", "State": "in-use", "SnapshotId": "snap-f23ec1c8", "CreateTime": "2013-09-17T00:55:03.000Z", "Size": 30 }, { "AvailabilityZone": "us-west-2a", "Attachments": [ { "AttachTime": "2013-09-18T20:26:16.000Z", "InstanceId": "i-4b41a37c", "VolumeId": "vol-2e410a47", "State": "attached", "DeleteOnTermination": true, "Device": "/dev/sda1" } ], "VolumeType": "standard", "VolumeId": "vol-2e410a47", "State": "in-use", "SnapshotId": "snap-708e8348", "CreateTime": "2013-09-18T20:26:15.000Z", "Size": 8 } ], "@metadata": { "statusCode": 200, "effectiveUri": "https:\/\/ec2.us-west-2.amazonaws.com", "headers": { "content-type": "text\/xml;charset=UTF-8", "transfer-encoding": "chunked", "vary": "Accept-Encoding", "date": "Wed, 06 May 2015 18:01:14 GMT", "server": "AmazonEC2" } } }
首先,我们可以利用以下命令,只从“卷”列表中检索第一个卷。
$firstVolume = $result->search('Volumes[0]');
现在,我们使用 wildcard-index
表达式 [*]
迭代整个列表,提取三个元素并重命名:将 VolumeId
重命名为 ID
,将 AvailabilityZone
重命名为 AZ
,并将 Size
保留为 Size
。我们可以将 multi-hash
表达式置于 wildcard-index
表达式之后,提取并重命名这些元素。
$data = $result->search('Volumes[*].{ID: VolumeId, AZ: AvailabilityZone, Size: Size}');
这样我们就有了如下的 PHP 数据:
array(2) { [0] => array(3) { 'AZ' => string(10) "us-west-2a" 'ID' => string(12) "vol-e11a5288" 'Size' => int(30) } [1] => array(3) { 'AZ' => string(10) "us-west-2a" 'ID' => string(12) "vol-2e410a47" 'Size' => int(8) } }
在 multi-hash
表示法中,您还可以使用串联的键(例如 key1.key2[0].key3
)提取深度嵌套在结构中的元素。以下示例利用 Attachments[0].InstanceId
键演示此功能,别名指定为简单的 InstanceId
。(在大多数情况下,JMESPath 表达式会忽略空格。)
$expr = 'Volumes[*].{ID: VolumeId, InstanceId: Attachments[0].InstanceId, AZ: AvailabilityZone, Size: Size}'; $data = $result->search($expr); var_dump($data);
上一表达式会输出以下数据:
array(2) { [0] => array(4) { 'ID' => string(12) "vol-e11a5288" 'InstanceId' => string(10) "i-a071c394" 'AZ' => string(10) "us-west-2a" 'Size' => int(30) } [1] => array(4) { 'ID' => string(12) "vol-2e410a47" 'InstanceId' => string(10) "i-4b41a37c" 'AZ' => string(10) "us-west-2a" 'Size' => int(8) } }
您还可以利用 multi-list
表达式筛选多个元素:[key1, key2]
。此表达式会将每个对象筛选出的所有属性放入单个排序列表中,不考虑类型。
$expr = 'Volumes[*].[VolumeId, Attachments[0].InstanceId, AvailabilityZone, Size]'; $data = $result->search($expr); var_dump($data);
运行上一搜索会生成以下数据:
array(2) { [0] => array(4) { [0] => string(12) "vol-e11a5288" [1] => string(10) "i-a071c394" [2] => string(10) "us-west-2a" [3] => int(30) } [1] => array(4) { [0] => string(12) "vol-2e410a47" [1] => string(10) "i-4b41a37c" [2] => string(10) "us-west-2a" [3] => int(8) } }
使用 filter
表达式按特定字段的值筛选结果。以下示例查询仅输出 us-west-2a
可用区中的卷。
$data = $result->search("Volumes[?AvailabilityZone ## 'us-west-2a']");
JMESPath 也支持函数表达式。假设您希望运行的查询与上述查询相同,但要检索以“us-”开头的 AWS 区域中的所有卷。以下表达式使用 starts_with
函数,传递 us-
文本字符串。然后将此函数的结果与 JSON 文本值 true
进行比较,仅传递通过筛选投影返回 true
的筛选断言结果。
$data = $result->search('Volumes[?starts_with(AvailabilityZone, 'us-') ## `true`]');
从分页工具提取数据
正如您可以通过 AWS SDK for PHP 版本 3 中的 Paginator 指南了解到的,Aws\ResultPaginator
对象可用于从可分页的 API 操作生成结果。您可以利用AWS SDK for PHP提取并迭代使用 Aws\ResultPaginator
对象筛选出的数据,也就是针对迭代器实施扁平化映射
假设您希望创建 iterator
,以仅从存储桶生成大于 1 MB 的对象。要做到这一点,应首先创建 ListObjects
分页工具,然后为该分页工具应用 search()
函数,针对分页数据创建扁平化映射的迭代器。
$result = $s3Client->getPaginator('ListObjects', ['Bucket' => 't1234']); $filtered = $result->search('Contents[?Size > `1048576`]'); // The result yielded as $data will be each individual match from // Contents in which the Size attribute is > 1048576 foreach ($filtered as $data) { var_dump($data); }