AWS SDK for PHP 버전 3의 JMEsPath 표현식 - AWS SDK for PHP

AWS SDK for PHP 버전 3의 JMEsPath 표현식

JMESPath를 사용하여 JSON 문서에서 요소를 추출하는 방법을 선언적으로 지정할 수 있습니다. AWS SDK for PHP에서는 jmespath.php에 의존하여 일부 상위 수준의 추상화(예: AWS SDK for PHP 버전 3의 페이지네이터, AWS SDK for PHP 버전 3의 Waiter)를 제공하고, Aws\ResultInterfaceAws\ResultPaginator에서 JMESPath 검색을 노출합니다.

온라인 JMESPath 예제를 통해 브라우저에서 JMESPath를 사용해 볼 수 있습니다. JMESPath 사양에서 언어(사용 가능한 표현식 및 함수 포함)에 대해 자세히 알아볼 수 있습니다.

AWS CLI는 JMESPath를 지원합니다. CLI 출력을 위해 작성된 표현식은 AWS SDK for PHP용으로 작성된 표현식과 100% 호환됩니다.

결과에서 데이터 추출

Aws\ResultInterface 인터페이스에는 JMESPath 표현식을 기반으로 결과 모델에서 데이터를 추출하는 search($expression) 메서드가 있습니다. JMESPath 표현식을 사용하여 결과 객체에서 데이터를 쿼리하면 보일러플레이트 조건부 코드를 제거하고, 추출 중인 데이터를 자세히 나타낼 수 있습니다.

작동 방식을 보여 주기 위해 먼저 아래와 같은 기본 JSON 출력으로 시작합니다. 여기서는 별도의 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 expression [*]를 사용하여 전체 목록을 반복하고 세 요소를 추출한 후 VolumeIdID로, AvailabilityZoneAZ로 이름을 바꾸고 SizeSize로 그대로 둡니다. 이러한 요소를 추출한 후 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 expression:[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에서는 함수 표현식도 지원합니다. 위와 동일한 쿼리를 실행하지만 이번에는 AWS 리전에서 “us-”로 시작하는 모든 볼륨을 검색한다고 가정합니다. 다음 표현식에서는 starts_with 문자열 리터럴을 전달하여 us- 함수를 사용합니다. 그런 다음 필터 투영을 통해 true를 반환한 필터 조건자의 결과만 전달하여 이 함수의 결과를 true JSON 리터럴 값과 비교합니다.

$data = $result->search('Volumes[?starts_with(AvailabilityZone, 'us-') ## `true`]');

페이지네이터에서 데이터 추출

AWS SDK for PHP 버전 3의 페이지네이터 가이드에서 살펴본 대로 Aws\ResultPaginator 객체는 페이징 가능한 API 작업에서 결과를 출력하는 데 사용됩니다. AWS SDK for PHP를 사용하면 Aws\ResultPaginator 객체에서 필터링된 데이터를 추출하여 반복할 수 있습니다. 이때 JMESPath 표현식의 결과가 맵 함수인 반복자에 대해 flat-map을 구현해야 합니다.

버킷에서 1MB보다 큰 객체만 출력하는 iterator를 생성한다고 가정합니다. 이렇게 하려면 ListObjects 페이지네이터를 생성한 다음 search() 함수를 페이지네이터에 적용하여 페이지 지정된 데이터에 대해 flat-map 반복자를 생성합니다.

$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); }