我有一个带有前缀(或"文件夹")的AWS S3存储桶,名为/photos
。那个"包含"一堆图像文件,甚至更少EVENT.json
个文件。天真的表现可能如下所示:
EVENT.json
文件的对象包含对任意数量的图像文件的路径引用,该图像文件将图像分组为特定事件。使用上面的示例,image1.jpg和image2.jpg可以出现在1_EVENT.json中,而image3.jpg可能属于2_EVENT.json。
随着存储桶变大,我对分析结果感兴趣。我只想在S3中一次请求一个页面,因为我需要它们。我遇到的问题是我想通过包含单词" EVENT"的键专门页面。我发现如果没有带回所有对象然后过滤或迭代结果,这很难实现。
使用S3 Paginator,我能够进行分页工作。假设我的PageSize
和MaxItems
设置为6,这就是我可能会在第一页上找到的内容:
/photos/
/photos/image1.jpg
/photos/image2.jpg
/photos/1_EVENT.json
/photos/image3.jpg
/photos/2_EVENT.json
S3的扁平结构意味着它根据前缀对桶中的所有对象进行分页,并根据分页参数进行限制和分页。这意味着我可以轻松地获取多个EVENT.json文件,或者根本不会获取任何文件,具体取决于页面。
所以我正在寻找更多的内容:
/photos/1_EVENT.json
/photos/2_EVENT.json
/photos/3_EVENT.json
/photos/4_EVENT.json
/photos/5_EVENT.json
/photos/6_EVENT.json
没有首先必须请求所有对象,然后以某种方式对结果集进行切片;这正是我目前正在做的事情:
client = boto3.client('s3')
paginator = client.get_paginator('list_objects_v2')
page_iterator = paginator.paginate(
Bucket=app.config.get('S3_BUCKET'),
Prefix="photos/") # Left PaginationConfig MaxItems & PageSize off intentionally
filtered_iterator = page_iterator.search(
"Contents[?contains(Key, `EVENT`)][]")
for page in filtered_iterator:
# Do stuff.
pass
以上是非常昂贵的,没有分页,但它确实给了我一个包含我的" EVENT"搜索字符串。
我特别希望使用boto3通过S3分页仅 EVENT.json对象的结果,而不会在每次请求时返回和过滤所有对象。这可能吗?
编辑:我已经将请求缩小到只有photos/
前缀的对象。这是因为还有其他"文件夹"在我的桶中也可能包含EVENT文件。这使我无法使用EVENT或EVENT.json作为我的前缀,因为响应可能会受到来自其他文件夹的文件的污染。
答案 0 :(得分:3)
最简单的方法是重新运行文件名结构,使EVENT文件遵循模式photos/EVENT_*.json
而不是photos/*_EVENT.json
。然后,您可以使用photos/EVENT
的公共前缀。
除此之外,我认为您使用的昂贵方法实际上是唯一可行的方法。
答案 1 :(得分:0)
您可以在boto中的某个搜索功能上添加前缀选项。这将大大减少它必须扫描的文件数量。但是,如果您必须在字符串中间搜索带有通配符的字符串,我知道它必须扫描存储桶中的所有对象,那么您必须通过这些对象进行通配符搜索。
例如:
$('body').click('.dropdown-menu li a[href="#"]', function(e) {e.preventDefault() });
虽然我无法回想起boto功能。