1、題記
這是stackoverflow上一篇精彩的問答。
原文不大好了解,我做了梳理+圖解;
原文是ES早期版本,部分寫法已不适用,所有DSL我在6.X上進行了重寫和驗證;
針對原文内容做了擴充。
2、知識庫全文檢索問題抛出
重新審視一個停滞不前的項目,并尋求建議,對數千個“舊”文檔進行現代化改造,
最終期望效果:通過網絡通路這些文檔。
文檔以各種格式存在,有些已經過時:
- .doc,
- PageMaker,
- 硬拷貝hardcopy (OCR),
-
PDF
……
很多文檔已經被轉化成掃描版的PDF,之前我們認為PDF類型是最終的文檔格式,現在看來,我們想聽聽建議(比如:xml是不是更好呢?)
核心需求點:
1、一旦所有文檔都采用通用格式,我們希望通過網頁界面提供其内容并提供搜尋服務。
2、我們希望通過搜尋,能夠靈活地隻傳回整個文檔的部分頁面(我相信的Lucene / elasticsearch使這成為可能?!?)
3、如果所有文檔是XML是否會更加靈活?
4、如何存儲、在哪裡存儲XML?是直接存儲在資料庫中還是存儲成檔案系統中的檔案?關于文檔中的嵌入式圖像/圖表呢?
以上,希望得到回複。
注解:xml隻是提問者的當時初步的了解。
3、精彩回複
我将推薦ElasticSearch,我們先解決這個問題并讨論如何實作它:
這有幾個部分:
- 從文檔中提取文本以使它們可以索引(indexable),以備檢索;
- 以全文搜尋形式提供此文本;
- 高亮顯示文檔片段;
- 知道文檔中的哪些段落可用于分頁;
- 傳回完整的文檔。
ElasticSearch可以提供什麼:
- ElasticSearch(如Solr)使用Tika從各種文檔格式中提取文本和中繼資料;
- Elasticsearch提供了強大的全文搜尋功能。它可以配置為以适當的語言分析每個文檔,它可以借助boost提高某些字段的權重(例如,标題比内容更重要),ngrams分詞等标準Lucene操作;
- Elasticsearch可以高亮顯示搜尋結果;
- Elasticsearch不知道這些片段在您的文檔中出現的位置;
- Elasticsearch可以将原始文檔存儲為附件,也可以存儲并傳回提取的文本。但它會傳回整個文檔,而不是一個頁面。
【直譯】您可以将整個文檔作為附件發送到ElasticSearch,并且可以進行全文搜尋。但是關鍵點在于上面的(4)和(5):知道你文檔中的位置,并傳回文檔的某些部分。存儲單個頁面可能足以滿足您的“我在哪裡”的目的,但是您希望将它們分組,以便在搜尋結果中傳回文檔,即使搜尋關鍵字出現在不同的頁面上。
任務分解:
3.1 索引部分——将文檔存儲在ElasticSearch中。
使用Tika(或任何你喜歡的)來從每個文檔中提取文本。将其保留為純文字或HTML格式以保留一些格式。
(忘記XML,不需要它)。
每個文檔提取中繼資料:标題,作者,章節,語言,日期等。
将原始文檔存儲在您的檔案系統中,并記錄路徑,以便以後可以使用。
在ElasticSearch中,索引包含所有中繼資料和可能的章節清單的“doc”文檔。
将每個頁面索引為“page”文檔,其中包含:
- 包含“doc”文檔ID的父字段(請參閱下面的“父子關系”)
- 文本
- 頁碼
- 也許章節标題或編号
- 您想要搜尋的任何中繼資料
存儲必備——父子文檔關系:
通常,在ES(和大多數NoSQL解決方案)中,每個文檔/對象都是獨立的 - 沒有真正的關系。
通過建立“doc”和“page”之間的父子關系,ElasticSearch確定子文檔(即“頁面”)與父文檔(“doc”)存儲在同一分片上。
這使您能夠運作has_child等的查詢方式,它将根據“page”的内容找到最比對的“doc”。
圖解示例:

二、檢索部分——
現在進行搜尋。
你如何做到這一點取決于你想如何展示你的結果
- 按頁面page分組,
- 按文檔doc分組。
通過頁面的結果很容易。
此查詢傳回比對頁面的清單(每個頁面全部傳回)以及頁面中高亮顯示的片段清單。
舉例如下:
POST /my_index/page/_search?pretty=1
{
"query" : {
"match" : {
"text" : "interesting keywords"
}
},
"highlight": {
"pre_tags": [
"<span style=\"color:red\">"
],
"post_tags": [
"</span>"
],
"require_field_match": true,
"fields": {
"title": {}
}
}
}
顯示包含文本高亮字段的“doc”分組有點棘手。 它不能用一個單一的查詢來完成。
一種方法可能是:
第1步:通過對其子(“頁面”)查詢,傳回最比對的父級(“doc”)。
POST /my_index/doc/_search?pretty=1
{
"query": {
"has_child": {
"type": "page",
"query": {
"bool": {
"must": [
{
"match": {
"text": "interesting keywords"
}
},
{
"term": {
"type": "page"
}
},
{
"term": {
"factor": "5"
}
}
]
}
},
"score_mode": "sum"
}
}
}
第2步:從上述查詢中收集“doc”ID 發出新查詢,從比對的“頁面”文檔中擷取片段。
GET /my_index/page/_search?pretty=1
{
"query" : {
"bool" : {
"must":{
"query" : {
"match" : {
"text" : "interesting keywords"
}
}},
"filter" : {
"terms" : {
"doc_id" : [1,2,3]
}
}
}
},
"highlight" : {
"fields" : {
"text" : {}
}
}
}
第3步:在您的應用程式中,将上述查詢的結果按doc分組并顯示出來。
使用第二個查詢的搜尋結果,您已經擁有了可供顯示的頁面的全文。要轉到下一頁,您可以搜尋它:
GET /my_index/page/_search?pretty=1
{
"query" : {
"constant_score" : {
"filter" :
[
{
"term" : {
"doc_id" : 1
}
},
{
"term" : {
"page" : 2
}
}
]
}
},
"size" : 1
}
或者,給“頁面”文檔提供一個由doc_id _doc_id _ page_num(例如123_2)組成的ID,然後您可以通過如下的檢索擷取該頁面:
curl -XGET'http://127.0.0.1:9200/my_index/page/123_2
3、擴充
Tika是一個内容分析工具,自帶全面的parser工具類,能解析基本所有常見格式的檔案,得到檔案的metadata,content等内容,傳回格式化資訊。總的來說可以作為一個通用的解析工具。特别對于搜尋引擎的資料抓去和處理步驟有重要意義。
Tika是Apache的Lucene項目下面的子項目,在lucene的應用中可以使用tika擷取大批量文檔中的内容來建立索引,非常友善,也很容易使用。
Apache Tika toolkit可以自動檢測各種文檔(如word,ppt,xml,csv,ppt等)的類型并抽取文檔的中繼資料和文本内容。
Tika內建了現有的文檔解析庫,并提供統一的接口,使針對不同類型的文檔進行解析變得更簡單。Tika針對搜尋引擎索引、内容分析、轉化等非常有用。
4、有沒有現成的開源實作呢?
https://github.com/RD17/ambarAmbar是一個開源文搜尋引擎,具有自動抓取,OCR識别,标簽分類和即時全文搜尋功能。
Ambar定義了在工作流程中實作全文本文檔搜尋的新方法:
- 輕松部署Ambar和一個單一的docker-compose檔案
- 通過文檔和圖像内容執行類似Google的搜尋
- Ambar支援所有流行的文檔格式,如果需要的話可以執行OCR
- 标記您的檔案
- 使用簡單的REST
- Api将Ambar內建到您的工作流程中
參考:
http://t.cn/R1gTMw4 http://t.cn/8FYfhE2 http://t.cn/R1gTK3M http://t.cn/R1gT6GY http://t.cn/RaPOswu作者:銘毅天下
來源:CSDN
原文:
https://blog.csdn.net/laoyang360/article/details/80616320版權聲明:本文為部落客原創文章,轉載請附上博文連結!