一、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.找到最相關的高亮片段;
本階段主要通過實際命中記錄的查詢關鍵字,對得到的高亮片段進行打分,從而找到跟查詢最相關的高亮片段;
要計算高亮片段的匹配情況,有兩種主要的方式
- 高亮處理的時候實時計算匹配情況,這樣就需要針對每個高亮片段創建臨時索引,並執行查詢語句來獲取匹配信息;
- 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來包裹高亮片段中的查詢關鍵字;