在數字時代,圖像數據的管理已成為數據架構的一部分。然而,隨之而來的挑戰是如何有效地索引和檢索這些圖像文件。
這不僅涉及存儲,更重要的是如何根據特定的屬性(如文件名中的數字)進行排序,以便用戶可以按照預期的順序查看圖像。
如下問題來自Elastic 釘釘技術交流群:
圖片
在Elasticsearch中,我們經常面對需要對數據進行排序的需求。單就排序,咱們之前有過幾篇文章分析不同業務場景的排序實現。
僅就上圖中的文件名進行排序,會怎么樣呢?我們構造一下數據,執行一下看。
POST /my_photos/_bulk{ "index" : { "_id" : "1" } }{ "photo_id" : "photo1.jpg", "upload_date" : "2024-02-01T10:00:00" }{ "index" : { "_id" : "2" } }{ "photo_id" : "photo2.jpg", "upload_date" : "2024-02-01T10:05:00" }{ "index" : { "_id" : "3" } }{ "photo_id" : "photo12.jpg", "upload_date" : "2024-02-01T10:10:00" }{ "index" : { "_id" : "4" } }{ "photo_id" : "photo111.jpg", "upload_date" : "2024-02-01T10:15:00" }### 執行檢索GET /my_photos/_search{ "query": { "match_all": {} }, "sort": [ { "photo_id.keyword": { "order": "asc" } } ]}
召回結果,同圖中后半部分結果一致。
圖片
結果并沒有達到預期。
而可行的解決方案,還得從文件名入手才可以。圖像文件名包含數字,需要根據這些數字進行排序,這才是根本!
我們采用兩種不同的解決方案來嘗試解決這個問題。
第一種:基于腳本排序。
第二種:復雜問題簡單化,預處理管道拆分出數值字段,基于數值排序。
使用 _script 進行排序是一種靈活的方法,它允許我們編寫自定義腳本來解析文件名并提取排序依據的數字。
GET /my_photos/_search{ "query": { "match_all": {} }, "sort": { "_script": { "type": "number", "script": { "lang": "painless", "source": """ String photoId = doc['photo_id.keyword'].value; if (photoId == null) return 0; Matcher m = /[0-9]+/.matcher(photoId); if (m.find()) { return Integer.parseInt(m.group(0)); } else { return 0; } """ }, "order": "asc" } }}
執行結果已經有序:
圖片
上述腳本基于正則表達式從photo_id字段中查找并提取出數字,如果找到就返回這個數字,如果找不到就返回0。
這樣的操作對于根據數字對文檔進行排序非常有用。
雖然這種方法非常強大,但它可能會因為腳本的執行而影響查詢性能,數據量巨大的時候,咱們要慎用!
除了上面的方案,另一種方法是在索引數據時使用Ingest管道預處理圖像文件名。
這樣可以在數據索引時就提取出文件名中的數字并存儲在一個專門的字段中。
這種方法的好處是可以顯著提高排序的效率,因為數字已經被預處理并作為數值類型存儲,使得排序操作更加快速。
就是開頭咱們提到的復雜問題簡單化。
PUT _ingest/pipeline/extract_photo_number{ "description": "Extracts numbers from photo_id and stores it in photo_number", "processors": [ { "grok": { "field": "photo_id", "patterns": ["%{NUMBER:photo_number:int}"] } } ]}DELETE my_photos_20240201### 創建索引的時候,記得指定上面創建好的預處理管道。### 新增的字段photo_number,和上面的預處理管道獲取的字段一一對應。PUT my_photos_20240201{ "settings": { "default_pipeline":"extract_photo_number" }, "mappings": { "properties": { "photo_id": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "photo_number": { "type": "long" }, "upload_date": { "type": "date" } } }}### 批量寫入數據POST /my_photos_20240201/_bulk{ "index" : { "_id" : "1" } }{ "photo_id" : "photo1.jpg", "upload_date" : "2024-02-01T10:00:00" }{ "index" : { "_id" : "2" } }{ "photo_id" : "photo2.jpg", "upload_date" : "2024-02-01T10:05:00" }{ "index" : { "_id" : "3" } }{ "photo_id" : "photo12.jpg", "upload_date" : "2024-02-01T10:10:00" }{ "index" : { "_id" : "4" } }{ "photo_id" : "photo111.jpg", "upload_date" : "2024-02-01T10:15:00" }### 執行檢索和排序POST my_photos_20240201/_search{ "query": { "match_all": {} }, "sort": [ { "photo_number": { "order": "asc" } } ]}
官方文檔參考:
https://www.elastic.co/guide/en/elasticsearch/reference/current/grok-processor.html
執行結果如下:
圖片
與腳本排序對比可以看出:
本文探討了在Elasticsearch中對包含數字的圖像文件名進行排序的挑戰及其解決方案。
在選擇哪種方案時,我們需要考慮實際需求和系統資源。
如果對性能有較高要求,預處理方案更為合適。但如果需求復雜多變,可能需要腳本排序的靈活性。
我更想跟大家探討的是:未來的數據建模應考慮到數據的索引和查詢模式。
例如,如果我們知道將來需要按照文件名中的數字排序,那么在設計數據模型時就應該考慮到這一點,以便于實現高效的查詢。
前置考慮得越充分,后面就越省事!
本文鏈接:http://www.tebozhan.com/showinfo-26-71940-0.html來自釘釘群的問題—Elasticsearch 如何實現文件名自定義排序?
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com