Как я могу отфильтровать объекты S3 по размеру, используя AWS SDK для PHP v3 Aws / ResultPaginator-> Search и выражение JMESPath? - PullRequest
0 голосов
/ 14 февраля 2020

Мне нужна помощь с фильтрацией результатов S3 с использованием AWS SDK для PHP v3 и JMESPath. Фильтрация по номеру не работает с PHP SDK, как показывают документация JMESPath и примеры в Интернете.

<?php
// test.php

use Aws\S3\S3Client;

// Create S3 client
$s3 = new S3Client([
    'version' => 'latest',
    'region'  => 'us-east-1'
]);

$bucket = 'my-bucket-name';
$prefix = 'path/to/my/objects';

// Call list-objects-v2
$awspaginator = $s3->getPaginator('ListObjectsV2', [
    'Bucket' => $bucket,
    'Prefix' => $prefix
]);

// Apply filter to paginator
$jmes = "reverse(Contents[?Size>`0`].{Key: Key, Date: LastModified, Size: Size}) | [-10:]";
$results = $awspaginator->search($jmes);

// Echo results
$i = 0;
foreach ($results as $result) {
    echo "\nResult: " . print_r($result);
    $i++;
}
echo "\nCount: " . $i . PHP_EOL;
?>

Это выводит Количество: 0

Но если я заменю Size> `0` на StorageClass=='STANDARD', я получу 10 самых последних объектов, как и ожидалось.

Я безуспешно пытался использовать следующие выражения размера.

  • Size>0 // возвращает ошибку: неожиданный токен числа
  • Size>'0' // успешно: возвращает нет результаты
  • Size>`0` // успешно: не возвращает результатов
  • Size!=`0` // возвращает результаты, но не отфильтровывает объекты нулевого размера
  • Size!=\"0\" // возвращает результаты, но не отфильтровывают объекты нулевого размера

Обратите внимание, что запрос s2api работает просто отлично, поэтому, похоже, это связано с методом поиска PHP SDK.

--bucket my-bucket-name \
--prefix path/to/my/objects \
--query "reverse(Contents[?Size>\`0\`].{Key: Key, Date: LastModified, Size: Size}) | [-10:]"

Любая помощь приветствуется!

1 Ответ

1 голос
/ 27 марта 2020

Я изо всех сил пытаюсь найти это документированное где угодно, но кажется, что Size не распакован как строка. Я смог заставить ваш пример работать с [?to_number(Size)>`0`] или даже с [?Size!='0'].

Это похоже на ошибку или, по крайней мере, сбой в документации, так как состояние документа:

CLI AWS поддерживает JMESPath. Выражения, которые вы пишете для вывода CLI, на 100 процентов совместимы с выражениями, написанными для AWS SDK для PHP.

https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/guide_jmespath.html

Только То, что я смог найти даже со ссылкой на это поведение, лишь незначительно связано:

https://forums.aws.amazon.com/message.jspa?messageID=752541#jive -message-312324

Здесь проблема в том, что API DynamoDB ожидает получения чисел в виде строк, и представитель Amazon отмечает, что такое поведение: а) потому что SDK должен поддерживать 32-разрядные среды, которые не могут обрабатывать целые числа более 2 миллиардов, и б) в целом все AWS SDK автоматически генерируется из набора файлов данных, не зависящих от языка c, и они предпочитают избегать создания исключений, когда они могут этого избежать. Кажется, это подразумевает, что использование строк в качестве целых чисел может происходить в широком диапазоне по всему SDK. Тем не менее, я не могу найти никаких упоминаний в других местах.


Независимо от того, является ли это преднамеренным, похоже, потому что Api / Parser / XmlParser PHP SDK не имеет сопоставления для тип long, который Size объявлен как. Здесь возвращается к стандартному поведению при разборе его в виде строки:

https://github.com/aws/aws-sdk-php/blob/master/src/Api/Parser/XmlParser.php#L23 -L31

...