首先還是說一下背景,工作中用到了 elasticsearch 的檢索以及高亮展示蛹找,但是索引中的content
字段是讀取的大文本內(nèi)容肚豺,所以后果就是索引的單個字段很大,造成單獨檢索請求的時候速度還可以谷异,但是加入高亮之后檢索請求的耗時就非常的慢了分尸。所以本文從更換高亮器類型的角度來解決因為高亮造成的檢索請求緩慢的問題。
ES的抵消策略
在文章開始前先簡單介紹一個elasticsearch的策略晰绎,為了在檢索的字段中創(chuàng)建出一個有意義的高亮片段寓落,高亮器會使用原始文本的開始和結(jié)束字符串的偏移量,偏移量的獲取可以從一下方式獲得
-
postings list
:如果在mapping
中index_options
設(shè)置為offsets
荞下,unified
高亮器使用此信息高亮顯示文檔而不用再次分析文本伶选。 -
term vectors
:如果我們在mapping
中設(shè)置term_vector
為with_positions_offsets
,則unified
高亮器會自動使用term_vector
來高亮顯示尖昏,對于大于1M
的大字段仰税,使用term_vector
速度會很快,fvh
高亮器就是使用的term_vector
抽诉。 -
plain highlighting
:當unified
沒有其他的選擇的時候會使用plain
模式陨簇,它會創(chuàng)建了一個微小的內(nèi)存索引,并通過Lucene的查詢執(zhí)行計劃器重新運行原始查詢條件迹淌。plain
高亮器默認使用的就是此模式
大文本的純高亮展示可能需要大量的時間和內(nèi)存河绽,為了防止這種情況,es默認將大文本的字符數(shù)量限制為
1000000
唉窃,可以使用index.highlight.max_analyzed_offset
修改此默認設(shè)置
一耙饰、FVH高亮器簡介
FVH(Fast Vector Highlighter)是Elasticsearch高亮器中的一種算法,使用的是Lucene Fast Vector highlighter纹份,它能夠快速而準確地在文本中找到匹配的關(guān)鍵詞苟跪,并將其標記為高亮。相比于其他高亮器算法蔓涧,F(xiàn)VH在性能上有著顯著的優(yōu)勢件已,特別適用于大規(guī)模數(shù)據(jù)集和高并發(fā)的場景。
二元暴、FVH高亮器的使用方法
安裝
首先篷扩,確保已經(jīng)正確安裝了 Elasticsearch
version: '3.8'
services:
cerebro:
image: lmenezes/cerebro:0.8.3
container_name: cerebro
ports:
- "9000:9000"
command:
- -Dhosts.0.host=http://eshot:9200
networks:
- elastic
kibana:
image: docker.elastic.co/kibana/kibana:8.1.3
container_name: kibana
environment:
- I18N_LOCALE=zh-CN
- XPACK_GRAPH_ENABLED=true
- TIMELION_ENABLED=true
- XPACK_MONITORING_COLLECTION_ENABLED="true"
- ELASTICSEARCH_HOSTS=http://eshot:9200
- server.publicBaseUrl=http://192.168.160.234:5601
ports:
- "5601:5601"
networks:
- elastic
eshot:
image: elasticsearch:8.1.3
container_name: eshot
environment:
- node.name=eshot
- cluster.name=es-docker-cluster
- discovery.seed_hosts=eshot,eswarm,escold
- cluster.initial_master_nodes=eshot,eswarm,escold
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
- xpack.security.enabled=false
- node.attr.node_type=hot
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- D:\zuiyuftp\docker\es8.1\eshot\data:/usr/share/elasticsearch/data
- D:\zuiyuftp\docker\es8.1\eshot\logs:/usr/share/elasticsearch/logs
- D:\zuiyuftp\docker\es8.1\eshot\plugins:/usr/share/elasticsearch/plugins
ports:
- 9200:9200
networks:
- elastic
eswarm:
image: elasticsearch:8.1.3
container_name: eswarm
environment:
- node.name=eswarm
- cluster.name=es-docker-cluster
- discovery.seed_hosts=eshot,eswarm,escold
- cluster.initial_master_nodes=eshot,eswarm,escold
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
- xpack.security.enabled=false
- node.attr.node_type=warm
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- D:\zuiyuftp\docker\es8.1\eswarm\data:/usr/share/elasticsearch/data
- D:\zuiyuftp\docker\es8.1\eswarm\logs:/usr/share/elasticsearch/logs
- D:\zuiyuftp\docker\es8.1\eshot\plugins:/usr/share/elasticsearch/plugins
networks:
- elastic
escold:
image: elasticsearch:8.1.3
container_name: escold
environment:
- node.name=escold
- cluster.name=es-docker-cluster
- discovery.seed_hosts=eshot,eswarm,escold
- cluster.initial_master_nodes=eshot,eswarm,escold
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
- xpack.security.enabled=false
- node.attr.node_type=cold
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- D:\zuiyuftp\docker\es8.1\escold\data:/usr/share/elasticsearch/data
- D:\zuiyuftp\docker\es8.1\escold\logs:/usr/share/elasticsearch/logs
- D:\zuiyuftp\docker\es8.1\eshot\plugins:/usr/share/elasticsearch/plugins
networks:
- elastic
# volumes:
# eshotdata:
# driver: local
# eswarmdata:
# driver: local
# escolddata:
# driver: local
networks:
elastic:
driver: bridge
創(chuàng)建索引
在使用FVH高亮器之前,需要先創(chuàng)建一個索引茉盏,并將需要高亮的字段進行映射瞻惋。例如厦滤,我們要在content
字段中進行高亮,可以使用以下代碼:
PUT /example_target
{
"mappings": {
"properties": {
"content": {
"type": "text",
"analyzer": "ik_max_word",
"term_vector": "with_positions_offsets"
},
"title": {
"type": "text",
"analyzer": "ik_max_word",
"term_vector": "with_positions_offsets"
}
}
}
}
添加測試數(shù)據(jù)
POST example_target/_doc
{
"content":"中華人民共和國是否考慮是否就愛上速度加快分解ask計算機卡死撒中華上的飛機拉絲機是的地方記錄 卡就是開發(fā)建設(shè)看積分卡說了句 ask就瘋狂薩拉丁就發(fā)士大 sdf 看得見啊李開復 圣誕節(jié)卡了 夫哈數(shù)據(jù)庫中華啊歼狼,中華掏导,人民愛上中華",
"title":"中華人名共和國"
}
查詢并高亮
使用FVH高亮器進行查詢和高亮的過程如下所示:
GET example_target/_search
{
"query": {
"match": {
"content": "中華 愛上"
}
},
"highlight": {
"pre_tags": "<em>",
"post_tags": "</em>",
"require_field_match": "false",
"fields": {
"content": {
"type": "fvh",
"fragment_size": 18,
"number_of_fragments": 3
}
}
}
}
以上代碼中,我們通過match
查詢找到了包含關(guān)鍵詞的文檔羽峰,然后在highlight
內(nèi)容中指定了需要高亮的字段趟咆,這里是content
。執(zhí)行述查詢后梅屉,Elasticsearch將返回匹配的結(jié)果值纱,并在content
字段中添加了高亮標記。
數(shù)據(jù)量少的時候?qū)Ρ炔皇翘貏e明顯坯汤,所以在測試時虐唠,可以在索引中添加大量的測試數(shù)據(jù)進行測試,本人在測試過程中es的索引大小在
500M
左右惰聂,單個字段純文本大小也有1-2M
疆偿。此時這種數(shù)據(jù)規(guī)模下使用普通的高亮器在檢索請求時就已經(jīng)非常緩慢了,根據(jù)返回的數(shù)據(jù)量多少來決定搓幌,在取10
條數(shù)據(jù)時已經(jīng)能達到6
秒了杆故,但是在使用fvh
高亮器之后時間已經(jīng)進入毫秒級
三、FVH高亮器的參數(shù)配置
先看一下返回的數(shù)據(jù)結(jié)果在對照下面參數(shù)學習
{
"took" : 4,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 3,
"relation" : "eq"
},
"max_score" : 0.41193593,
"hits" : [
{
"_index" : "example_target",
"_id" : "f1rkC4oBCDmhQc2yo6PQ",
"_score" : 0.41193593,
"_source" : {
"content" : "中華人民共和國是否考慮是否就愛上速度加快分解ask計算機卡死撒中華上的飛機拉絲機是的地方記錄 卡就是開發(fā)建設(shè)看積分卡說了句 ask就瘋狂薩拉丁就發(fā)士大 sdf 看得見啊李開復 圣誕節(jié)卡了 夫哈數(shù)據(jù)庫中華啊溉愁,中華处铛,人民愛上中華"
},
"highlight" : {
"content" : [
"<em>中華</em>人民共和國是否考慮是否就<em>愛上</em>速度",
"sk計算機卡死撒<em>中華</em>上的飛機拉絲機是的地方記錄",
"夫哈數(shù)據(jù)庫<em>中華</em>啊,<em>中華</em>拐揭,人民<em>愛上</em>中華"
]
}
},
{
"_index" : "example_target",
"_id" : "G3Fi44kB4IVEhjafHXOf",
"_score" : 0.33311102,
"_source" : {
"content" : "中華人民共和國是否考慮是否就愛上速度加快分解ask計算機卡死撒中華上的飛機拉絲機是的地方記錄卡就是開發(fā)建設(shè)看積分卡說了句ask就瘋狂薩拉丁就發(fā)士大夫哈數(shù)據(jù)庫"
},
"highlight" : {
"content" : [
"<em>中華</em>人民共和國是否考慮是否就<em>愛上</em>速度",
"sk計算機卡死撒<em>中華</em>上的飛機拉絲機是"
]
}
},
{
"_index" : "example_target",
"_id" : "HHFt44kB4IVEhjafE3Ov",
"_score" : 0.31932122,
"_source" : {
"content" : "中華人民共和國是否考慮是否就愛上速度加快分解ask計算機卡死撒中華上的飛機拉絲機是的地方記錄 卡就是開發(fā)建設(shè)看積分卡說了句 ask就瘋狂薩拉丁就發(fā)士大 sdf 看得見啊李開復 圣誕節(jié)卡了 夫哈數(shù)據(jù)庫"
},
"highlight" : {
"content" : [
"<em>中華</em>人民共和國是否考慮是否就<em>愛上</em>速度",
"sk計算機卡死撒<em>中華</em>上的飛機拉絲機是的地方記錄"
]
}
}
]
}
}
通過上面的查詢請求中高亮參數(shù)的指定可以發(fā)現(xiàn)撤蟆,高亮器還是支持其他的參數(shù)的,那么我們下面將對幾個常用的參數(shù)進行說明
fragment_size
:指定每個高亮片段的長度堂污,默認為100
個字符枫疆。number_of_fragments
:指定返回的高亮片段數(shù)量,默認為5
個敷鸦。pre_tags
和post_tags
:分別指定高亮標記的前綴和后綴,默認為<em>
和</em>
寝贡。require_field_match
:指定是否要求所有字段都匹配關(guān)鍵詞才進行高亮扒披,默認為true
∑耘荩可以開啟關(guān)閉此參數(shù)對上面的title
字段進行校驗-
type
:指定fvh
高亮器碟案,除了fvh
之外還有unified
,plain
颇蜡。-
unified
是默認的高亮器价说,可以將文本分解為句子辆亏,并使用BM25算法對單個句子進行評分,還支持精確的短語高亮顯示鳖目,支持(fuzzy
扮叨,prefix
,regex
)高亮领迈。 -
plain
普通的高亮器彻磁,適用與簡單的查詢或者單個字段的匹配。為了準確的反應(yīng)查詢邏輯狸捅,它會在內(nèi)存中創(chuàng)建一個很小的索引衷蜓,來對原始的查詢語句進行執(zhí)行,來訪問當前更低級別的匹配信息尘喝。
-
在使用FVH
高亮器時磁浇,根據(jù)實際需求,可以靈活地調(diào)整這些參數(shù)朽褪,以獲得最佳的高亮效果置吓。
總結(jié)
通過本文的介紹,我們了解了Elasticsearch高亮器中的FVH
算法鞍匾,并學會了如何使用它為搜索結(jié)果增添亮點交洗。FVH
高亮器在性能和功能上都有著明顯的優(yōu)勢,對于大規(guī)模數(shù)據(jù)集和高并發(fā)的場景尤為適用橡淑。希望讀者通過本文的指引构拳,能夠更好地利用FVH
高亮器來提升搜索結(jié)果的可讀性和用戶體驗。
參考鏈接
https://www.elastic.co/guide/en/elasticsearch/reference/8.1/highlighting.html
如果感覺本文對你有所幫助歡迎點贊評論轉(zhuǎn)發(fā)收藏梁棠。如果你想了解更多關(guān)于ES的騷操作置森,更多實戰(zhàn)經(jīng)驗,點擊查看原文