2016-12-29 92 views
1

我有一個名爲/photos的前綴(或「文件夾」)的AWS S3存儲桶。該「包含」一堆圖像文件,甚至更少EVENT.json文件。一個天真的表示可能是這樣的:通過S3對象使用boto3匹配特定文件名的頁面

  • 我-真棒事件鬥
    • 照片
      • 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.json對象通過S3使用boto3而沒有返回和過濾所有對象的開銷每個請求。那可能嗎?

編輯:我已經把請求縮小到只與photos/前綴對象。這是因爲我的存儲桶中還有其他「文件夾」也可能包含EVENT文件。這阻止我使用EVENT或EVENT。json作爲我的前綴,因爲響應可能會受到來自其他文件夾的文件的污染。

+0

如果您只需要一個Amazon S3內容列表,並且您不需要它完美地更新,就可以使用[Amazon S3 Storage Inventory](http://docs.aws.amazon.com/AmazonS3/ latest/dev/storage-inventory.html)來存儲S3存儲桶中所有文件的每日CSV。 –

+0

@JohnRotenstein存儲清單似乎沒有提供任何有助於分頁結果的附加結構,並且僅限於根據[文檔](http://docs.aws.amazon.com/AmazonS3/latest /dev/storage-inventory.html#storage-inventory-how-to-set-up)。但是,如果我可以使用它來創建和維護具有給定前綴的EVENT文件的清單,則排定的清單可能值得等待。 – afilbert

回答

2

最簡單的方法是重新構建您的文件名結構以使EVENT文件遵循模式photos/EVENT_*.json而不是photos/*_EVENT.json。然後你可以使用一個通用的前綴photos/EVENT

簡而言之,我認爲你使用的昂貴的方法實際上是唯一的方法去解決它。

+0

請使用'\'反引號\''來轉義文件名; '*這裏*之間的東西*呈現爲斜體文字。 –

+0

不幸的是,這些文件名是在我進入項目之前開發的應用程序生成的。它已經在客戶流通中,並且很難改變。經過一段時間的研究之後,我得出結論,我要麼改變我們如何命名和組織文件,就像你所建議的那樣,要麼解決恢復所有對象的開銷。我不應該感到驚訝,因爲「簡單」是以S3服務的名義。我正在研究通過RDS緩存和分頁結果。 – afilbert

0

有一個前綴選項,你可以在博託的其中一個搜索功能上拋出。這將大大減少它必須掃描的文件數量。然而,如果你不得不在字符串的最後搜索帶有通配符的字符串,我知道它必須掃描桶中的所有對象,然後你必須通過通配符來搜索那些對象。

例如:

bucket.search_function(prefix="string") 

我不能,雖然召回博託功能關閉我的頭頂。

+0

我很遺憾已經使用前綴來限制我的結果到/ photos「文件夾」,否則我會使用EVENT作爲前綴並將其稱爲一天。不幸的是,在同一個桶中的其他「文件夾」中也有EVENT文件,我想避免污染我的/照片事件。 – afilbert