elasticsearch高亮之highlight原理


一、highlight簡介

highlight是提升用戶體驗的重要手段,搜索引擎通過高亮突出命中關鍵字等方式,方便用戶通過關鍵字周圍的信息快速的確認是否是自己希望的結果;

highlight功能通常包含以下三個主要的處理過程
1.將字段文本拆分為小的片段;
2.找出最相關的片段;
3.高亮查詢關鍵字;

二、elasticsearch的highlight功能

elasticsearch提供了專門的高亮請求參數highlight,返回的記過中也會包含對應的高亮信息;

在查詢語句中,我們要求對text字段進行高亮處理;

GET /twitter/_search
{
  "query": {
    "match": {
      "text": "Another"
    }
  },
  "highlight": {
    "fields": {
      "text": {}
    }
  }
}

elasticsearch默認使用em對命中關鍵字進行包裹處理;

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 0.6931472,
    "hits" : [
      {
        "_index" : "twitter",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 0.6931472,
        "_source" : {
          "fullname" : "Jane Doe",
          "text" : "Another twitter test ..."
        },
        "highlight" : {
          "text" : [
            "<em>Another</em> twitter test ..."
          ]
        }
      }
    ]
  }
}

高亮處理需要使用原始的字段值文本,所以elasticsearch需要保存字段的值,我們可以在字段的mapping中設置store為true,否則只能從_source字段中load對應字段值;

三、elasticsearch提供的三種highlighter

elasticsearch提供了以下三種highlighter

Unified highlighter

這個unified highlighter是elasticsearch的默認highlighter,其使用的是Lucene Unified Highlighter,它會將文本分割為句子片段,然后使用BM25算法計算每個句子片段的相似性得分;改highlighter支持phrase、fuzzy、prefix等查詢的高亮處理;

Plain highlighter

這個plain Highlighter使用的是標准的lucene Highlighter,其通過關鍵字的重要性及關鍵字的位置信息,嘗試盡量的體現查詢的匹配邏輯;

為了更加准確的體現查詢的邏輯,Plain Highlighter需要針對具體的查詢和命中文檔的每個字段進行實時的計算,其會在內存中創建一個小型的index,然后通過查詢計划重新執行一遍查詢,從而獲得高亮需要使用底層的匹配信息,所以其比較適合小型的字段;

Fast vector highlighter

這個fvh Highlighter使用的是Lucene Fast Vector Highlighter,其基於term_vector的數據結構,需要在mapping中將相應的字段設置為with_positions_offsets;其比較適合對大文本字段進行高亮處理;

四、Highlighter的高亮處理過程

Highlighter的主要工作就是通過傳入的查詢和命中的文檔,找到能夠最好反應匹配相關性的高亮片段;其主要需要完成以下三個工作;

1.將文本查分為小的高亮片段
本階段主要將字段值文本拆分為小的高亮片段,三種Highlighter的處理過程如下

Plain Highlighter首先使用字段對應的analyzer對文本進行分詞處理,然后通過得到的每個分詞的起止字符位置,依次截取fragment_size的文本段;由於根據固定的片段長度拆分,得到的片段效果往往很不理想;

Unified和fvh Highlighter都通過Java的BreakIterator進行拆分高亮片段,配合fragment_size可以得到比較完整的句子;

2.找到最相關的高亮片段;

本階段主要通過實際命中記錄的查詢關鍵字,對得到的高亮片段進行打分,從而找到跟查詢最相關的高亮片段;

要計算高亮片段的匹配情況,有兩種主要的方式

  1. 高亮處理的時候實時計算匹配情況,這樣就需要針對每個高亮片段創建臨時索引,並執行查詢語句來獲取匹配信息;
  2. index的時候進行相關分詞起止字符的統計信息處理和保存;
  • postings list,在字段mapping的時候,可以通過index_options來控制記錄到倒排索引中的分詞統計信息,通過設置offsets可以保存記錄分詞的起止信息;
  • term vector,elasticsearch提供的term_vector也記錄了分詞過程中產生的分詞的起止信息,也是在字段mapping的時候進行設置,需要設置為with_positions_offsets;

三種Highlighter的處理過程如下

Plain Highlighter首先會利用高亮片段生成的分詞在內存中創建一個index,並通過lucene查詢計划執行原始的查詢,然后通過命中信息獲得匹配的分詞,通過計算高亮片段的包含的不同查詢分詞的數量計算相關性得分;這里直接使用查詢分詞的boost(默認值)進行計算;

fvh Highlighter直接利用index的時候創建的term vector來得到高亮片段匹配的查詢分詞,其對高亮片段的評分算法跟Plain Highlighter類似,只不過這里會將命中的所有查詢分詞(包括重復的查詢分詞)計算在內;

unified Highlighter會嘗試優先使用term vectors,index中的postings list,否則只能跟plain Highlighter相同的方式進行實時計算;其使用BM25算法計算高亮片段的相似度;

3.Highlight高亮片段;

本階段主要進行輸出前的編碼和格式化,最后使用pre-tags、post-tags來包裹高亮片段中的查詢關鍵字;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM