2016-12-29 1 views
1

/photosと呼ばれる接頭辞(または「フォルダ」)を持つAWS S3バケットがあります。それには画像ファイルがたくさん含まれており、さらにファイル数はEVENT.jsonです。素朴な表現は次のようになります。boto3を使用して特定のファイル名に一致するS3オブジェクトを返します

  • 私-素晴らしい-イベントバケット
    • 写真
      • image1.jpg
      • image2.jpg
      • 1_EVENT.json
      • をimage3.jpg
      • 2_EVENT.json
      • ...

EVENT.jsonファイルは、特定のイベントにグループ化画像の画像ファイル、任意の量のパスの参照を含むオブジェクトを有します。上記の例を使用すると、image1.jpgとimage2.jpgは1_EVENT.jsonに表示され、image3.jpgは2_EVENT.jsonに属することがあります。

バケットが大きくなるにつれて、結果をページングすることに興味があります。私は必要なときにS3から一度にページを要求したいだけです。私が取り組んでいる問題は、「EVENT」という単語が含まれているキーで特にページすることです。私は、すべてのオブジェクトを取り戻し、結果をフィルタリングまたは反復することなく、達成することが困難であることを発見しています。

S3 Paginatorを使用して、私はページングを行うことができます。私PageSizeMaxItems 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」検索文字列を含むすべてのファイルのリストを与えるん。

具体的には、ののEVENT.jsonオブジェクトには、リクエストごとにすべてのオブジェクトを戻してフィルタするオーバーヘッドなしにboto3を使用してS3からオブジェクトを処理します。それは可能ですか?

EDIT:プレフィックスがphotos/のオブジェクトだけにリクエストを絞り込んでいます。これは、EVENTファイルを含む可能性のある他の「フォルダ」がバケットにあるためです。そうすれば、私はEVENTまたはEVENTを使用できなくなります。他のフォルダからのファイルによって応答が汚染される可能性があるため、jsonをプレフィックスとして使用します。

+0

Amazon S3コンテンツのリストが必要なだけで完全に最新のものである必要がない場合は、[Amazon S3 Storage Inventory](http://docs.aws.amazon.com/AmazonS3/)を使用できます。最新/ dev/storage-inventory.html)を使用して、S3バケット内のすべてのファイルの1日のCSVを保存します。 –

+0

@JohnRotensteinストレージインベントリは、ページング結果を支援する追加の構造を提供していないようであり、[documentation](http://docs.aws.amazon.com/AmazonS3/latest /dev/storage-inventory.html#storage-inventory-how-to-setup)。ただし、それを使用して特定のプレフィックスを持つEVENTファイルのインベントリを作成して維持することができれば、スケジュールされたインベントリは待つ価値があるかもしれません。 – afilbert

答えて

2

最も簡単な方法は、EVENTファイルがの代わりにphotos/*_EVENT.jsonのパターンに従うようにファイル名構造を再ハッシュすることです。次に、共通接頭辞photos/EVENTを使用できます。

私は、あなたが使用している高価な方法は実際にはそれを実行する唯一の方法だと思います。

+0

ファイル名をエスケープするには、 '\'バッククォート\ ''を使用してください。 '*ここの間のもの* 'はイタリック体で表示されます。 –

+0

ファイル名は残念ながら私がプロジェクトに入る前に開発されたアプリケーションによって生成されています。それはすでにクライアントの流通にあり、変更するのが難しいでしょう。これをしばらく見てから、ファイルの命名や編成方法を変更したり、提案したように変更したり、すべてのオブジェクトを戻すオーバーヘッドを解決したりする必要があります。 S3サービスの名前に「シンプル」があると私は驚いてはいけません。代わりに、RDSを使用して結果をキャッシュしてページングする方法を検討しています。 – afilbert

0

botoの検索機能の1つにスクロールできるプレフィックスオプションがあります。これにより、スキャンするファイルの量が大幅に削減されます。しかし、文字列の途中でワイルドカードを使用して文字列を検索する必要がある場合は、バケット内のすべてのオブジェクトをスキャンしなければならないことがわかっていましたが、それらのオブジェクトをワイルドカードで検索する必要があります。

例:

bucket.search_function(prefix="string") 

でも、私は私の頭の上からのboto機能を呼び出すことはできません。

+0

残念ながら私の結果を/ photos "フォルダ"に限定するためにプレフィックスを既に使用しています。そうでなければ、EVENTをプレフィックスとして使用して1日と呼んでいます。残念ながら、my/photosイベントを汚染しないようにしたい同じバケット内の他の "フォルダ"にもEVENTファイルがあります。 – afilbert

関連する問題