Есть способ сделать это с Афиной, но я не могу рекомендовать это. Я включил это ниже.
В зависимости от вашего приложения есть разные способы сделать это. Если файлы меняются не часто, и вы не возражаете возвращать результаты, которым несколько часов, я бы предложил использовать S3 Inventory , он периодически записывает список всех объектов в корзине. Для поиска файла вы просматриваете последний манифест инвентаря, находите списки инвентаря и просматриваете их (вы даже можете использовать Athena для запроса инвентаря, для этого есть руководство в документации ).
Если вам нужно быть более свежим, S3 Inventory не будет работать, поскольку он будет создавать новый листинг не чаще одного раза в день.
Если это так, вы можете либо просто перечислить все файлы в вашем корзине для каждого поиска, в зависимости от числа файлов, о которых мы говорим, это может быть очень медленным или очень быстрым - будет менее 1000 файлов. очень быстро, но после этого вам придется выполнять несколько запросов, разбирающих страницы по 1000 объектов за раз, или придумывать способ выполнить несколько параллельных операций подкачки, перечисляя все объекты, начиная с a
, в одном все операции начинаются с b
в другом и т. д.
Наиболее экономичное решение, если вы хотите быть в курсе и иметь быстрые ответы, - это хранить отдельный индекс объектов в вашей корзине. Обновите индекс, прослушивая S3 Уведомления о событиях . Прослушайте как создания, так и удаления и обновите индекс соответствующим образом Вы можете использовать ElasticSearch, Algolia или Postgres или любой другой сервис или базу данных с приличными полнотекстовыми возможностями для индекса - но это будет гораздо больше инфраструктуры для настройки, чем просто S3, конечно.
Если вы абсолютно хотите сделать это с Athena, это может быть сделано, но это не будет самым эффективным решением, и если у вас много файлов и они содержат много данных, это может в конечном итоге стоить вам немного, так что будьте осторожны.
Во всех таблицах Athena есть скрытый столбец с именем $path
, который содержит полный URI объекта S3, из которого была прочитана строка. Может использоваться и для фильтрации.
Если вы создадите такую таблицу:
CREATE EXTERNAL TABLE `listing` (`ignored` string)
STORED AS INPUTFORMAT 'org.apache.hadoop.mapred.TextInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION 's3://bucket_name/'
TBLPROPERTIES ('has_encrypted_data'='false')
это просто таблица с фиктивным столбцом, она может называться как угодно, она просто есть, потому что невозможно создать таблицу без столбцов. Просто убедитесь, что LOCATION
правильно.
Для поиска объектов это то, что вы делаете:
SELECT DISTINCT "$path"
FROM listing
WHERE "$path" LIKE '%foo%'
Хотя это может выглядеть аккуратно и решить вашу проблему, это ужасно неэффективный и дорогой способ сделать это. Афина перечислит все файлы в вашем ведре, затем прочитает их все, и вам придется заплатить как за операции S3, так и за отсканированные данные. Даже если Афина в конце концов только смотрит на клавиши S3, она не имеет никакой оптимизации, которая мешает ей читать их все.