如何優(yōu)化因為高亮造成的大文本(大字段)檢索緩慢問題

首先還是說一下背景,工作中用到了 elasticsearch 的檢索以及高亮展示蛹找,但是索引中的content字段是讀取的大文本內(nèi)容肚豺,所以后果就是索引的單個字段很大,造成單獨檢索請求的時候速度還可以谷异,但是加入高亮之后檢索請求的耗時就非常的慢了分尸。所以本文從更換高亮器類型的角度來解決因為高亮造成的檢索請求緩慢的問題。

ES的抵消策略

在文章開始前先簡單介紹一個elasticsearch的策略晰绎,為了在檢索的字段中創(chuàng)建出一個有意義的高亮片段寓落,高亮器會使用原始文本的開始和結(jié)束字符串的偏移量,偏移量的獲取可以從一下方式獲得

  • postings list:如果在mappingindex_options設(shè)置為offsets荞下,unified高亮器使用此信息高亮顯示文檔而不用再次分析文本伶选。
  • term vectors:如果我們在mapping中設(shè)置term_vectorwith_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_tagspost_tags:分別指定高亮標記的前綴和后綴,默認為<em></em>寝贡。

  • require_field_match:指定是否要求所有字段都匹配關(guān)鍵詞才進行高亮扒披,默認為true∑耘荩可以開啟關(guān)閉此參數(shù)對上面的title字段進行校驗

  • type:指定fvh高亮器碟案,除了fvh之外還有unifiedplain颇蜡。

    • unified 是默認的高亮器价说,可以將文本分解為句子辆亏,并使用BM25算法對單個句子進行評分,還支持精確的短語高亮顯示鳖目,支持(fuzzy扮叨,prefixregex)高亮领迈。
    • 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)驗,點擊查看原文

原文鏈接
https://mp.weixin.qq.com/s?__biz=MzIwNzYzODIxMw==&mid=2247486065&idx=1&sn=28ee03fd0e297eb0c5d62405446d4551&chksm=970e11dba07998cd53a3a16e39e396172c3e3b46f96bab0e097eeab08fefb93c63b0d48fe380#rd

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末符糊,一起剝皮案震驚了整個濱河市凫海,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌男娄,老刑警劉巖行贪,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異模闲,居然都是意外死亡建瘫,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進店門尸折,熙熙樓的掌柜王于貴愁眉苦臉地迎上來啰脚,“玉大人,你說我怎么就攤上這事实夹¢吓ǎ” “怎么了粒梦?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長荸实。 經(jīng)常有香客問我匀们,道長,這世上最難降的妖魔是什么泪勒? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任昼蛀,我火速辦了婚禮,結(jié)果婚禮上圆存,老公的妹妹穿的比我還像新娘叼旋。我一直安慰自己,他們只是感情好沦辙,可當我...
    茶點故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布夫植。 她就那樣靜靜地躺著,像睡著了一般油讯。 火紅的嫁衣襯著肌膚如雪详民。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天陌兑,我揣著相機與錄音沈跨,去河邊找鬼。 笑死兔综,一個胖子當著我的面吹牛饿凛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播软驰,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼涧窒,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了锭亏?” 一聲冷哼從身側(cè)響起纠吴,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎慧瘤,沒想到半個月后戴已,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡锅减,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年糖儡,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片上煤。...
    茶點故事閱讀 40,137評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖著淆,靈堂內(nèi)的尸體忽然破棺而出劫狠,到底是詐尸還是另有隱情拴疤,我是刑警寧澤,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布独泞,位于F島的核電站呐矾,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏懦砂。R本人自食惡果不足惜蜒犯,卻給世界環(huán)境...
    茶點故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望荞膘。 院中可真熱鬧罚随,春花似錦、人聲如沸羽资。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽屠升。三九已至潮改,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間腹暖,已是汗流浹背汇在。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留脏答,地道東北人糕殉。 一個月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像以蕴,于是被迫代替她去往敵國和親糙麦。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,086評論 2 355

推薦閱讀更多精彩內(nèi)容