天天看點

幹貨 | 知識庫全文檢索的最佳實踐

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/ambar

Ambar是一個開源文搜尋引擎,具有自動抓取,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

版權聲明:本文為部落客原創文章,轉載請附上博文連結!