Elasticsearch 通常用於字符串,數字,日期等數據類型的檢索,但是在 HCM、ERP 和電子商務等應用程序中經常存在對辦公文檔進行搜索的需求。今天的這篇文章中我們來講一下如何實現 PDF、DOC、XLS 等辦公文件的搜索,本解決方案適用於 Elasticsearch 5.0 以后的版本。
實現原理
首先把我們的 .pdf 文件進行 Base64 處理,然后上傳到 Elasticsearch 中的 ingest node 中進行處理。我們可以通過 Ingest attachment plugin 來使得 Elasticsearch 提取通用格式的文件附件比如 PPT、XLS及PDF。最終,數據進入到 Elasticsearch 的 data node 中以便讓我們進行搜索。
導入PDF文件到Elasticsearch中
准備PDF文件
我們可以使用 Word 或其它編輯軟件來生產一個 PDF 文件,暫且我們叫這個文件的名字為 sample.pdf,而它的內容非常簡單,在 sample.pdf 文件中,我們只有一句話:“I like this useful tool”。
安裝 Ingest attachment plugin
Ingest attachment plugin 允許 Elasticsearch 通過使用 Apache 文本提取庫 Tika 提取通用格式(例如:PPT,XLS 和 PDF)的文件附件。Apache Tika 工具包可從一千多種不同的文件類型中檢測並提取元數據和文本。所有這些文件類型都可以通過一個界面進行解析,從而使 Tika 對搜索引擎索引,內容分析,翻譯等有用。
需要注意的是,源字段必須是 Base64 編碼的二進制,如果不想增加在 Base64 之間來回轉換的開銷,則可以使用 CBOR 格式而不是 JSON,並將字段指定為字節數組而不是字符串表示形式,這樣處理器將跳過 Base64 解碼。
可以使用插件管理器安裝此插件,該插件必須安裝在集群中的每個節點上,並且每個節點必須在安裝后重新啟動。
sudo bin/elasticsearch-plugin install ingest-attachment
等我們安裝好這個插件后,我們可以通過如下的命令來查看該插件是否已經被成功安裝好了:
./bin/elasticsearch-plugin list
創建 attachment pipeline
在我們的 ingest node 上創建一個叫做 pdfattachment 的 pipleline:
PUT _ingest/pipeline/pdfattachment
{
"description": "Extract attachment information encoded in Base64 with UTF-8 charset",
"processors": [
{
"attachment": {
"field": "file"
}
}
]
}
轉換並上傳PDF文件的內容到Elasticsearch中
對於 Ingest attachment plugin 來說,它的數據必須是 Base64 的。我們可以在網站Base64 encoder 來進行轉換,我們可以直接通過下面的腳本來進行操作:
!/bin/bash
encodedPdf=`cat sample.pdf | base64`
json="{\"file\":\"${encodedPdf}\"}"
echo "$json" > json.file
curl -XPOST 'http://localhost:9200/pdf-test1/_doc?pipeline=pdfattachment&pretty' -H 'Content-Type: application/json' -d @json.file
在上面的腳本中,我們針對 sample.pdf 進行 Base64 的轉換,並生成一個叫做 json.file 的文件。在最后,我們把這個 json.file 文件的內容通過 curl 指令上傳到 Elasticsearch 中,我們可以在 Elasticsearch 中查看一個叫做 pdf-test1 的索引。
查看索引並搜索
可以通過如下的命令來查詢 pdf-test1 索引:
GET pdf-test1/_search
可以看出來,我們的索引中有一個叫做 content 的字段,它包含了我們的 pdf 文件的內容,這個字段可以同我們進行搜索。在上面我們也看到了一個很大的一個字段 file,它含有我們轉換過的 Base64 格式的內容。如果我們不想要這個字段,我們可以通過添加另外一個 remove processor 來除去這個字段:
PUT _ingest/pipeline/pdfattachment
{
"description": "Extract attachment information encoded in Base64 with UTF-8 charset",
"processors": [
{
"attachment": {
"field": "file"
}
},
{
"remove": {
"field": "file"
}
}
]
}