天天看點

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

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": {}

   }

 }

  }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

顯示包含文本高亮字段的“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"

               "factor": "5"

           }

         ]

       }

     },

     "score_mode": "sum"

}

21

22

23

24

25

26

27

28

29

30

第2步:從上述查詢中收集“doc”ID 發出新查詢,從比對的“頁面”文檔中擷取片段。

GET /my_index/page/_search?pretty=1

     "bool" : {

       "must":{

        "query" : {

           "match" : {

              "text" : "interesting keywords"

        }},

        "filter" : {

           "terms" : {

              "doc_id" : [1,2,3]

        }

  "highlight" : {

     "fields" : {

        "text" : {}

第3步:在您的應用程式中,将上述查詢的結果按doc分組并顯示出來。

使用第二個查詢的搜尋結果,您已經擁有了可供顯示的頁面的全文。要轉到下一頁,您可以搜尋它:

     "constant_score" : {

        "filter" :

           [

              {

                 "term" : {

                    "doc_id" : 1

                 }

              },

                    "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