<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Elasticsearch 警惕使用 wildcard 檢索!然后呢?

          共 6817字,需瀏覽 14分鐘

           ·

          2021-03-27 15:10

          1、wildcard 檢索定義

          wildcard 檢索可以定義為:支持通配符的模糊檢索。

          類似 Mysql 中的 like 模糊匹配,如下所示:

          Elasticsearch 中的 wildcard 使用方式如下:

          通配符運算符是匹配一個或多個字符的占位符。

          通配符支持兩種:

          • ? : 支持模糊匹配單個字符。舉例:Ma?s 僅能匹配:Mars, Mass, 和 Maps。
          • : 支持模糊匹配零個或者多個字符。舉例:Ma*s 能匹配:Mars, Matches 和 Massachusetts等。

          2、全局視野——wildcard 檢索所處位置

          全局認知非常重要,檢索核心類型大致(非嚴謹、精確)分為:精準匹配檢索(Term-level queries)和基于分詞的全文匹配檢索(Full text queries)。

          全文匹配檢索細分如下:

          精準匹配檢索細分如下:

          也就是:wildcard 是和Term、Terms檢索平級的檢索。

          3、wildcard 檢索適用場景

          適用于:召回率要求高的業(yè)務場景。

          基于分詞的全文檢索,可能會導致明明存在,但是檢索不到。可能的原因如下:

          • 原因1:基礎詞庫不完備;
          • 原因2:分詞粒度不精確。

          舉個例子一看就明白了:

          前置說明:

          • 1、純屬舉例,不涉及針對具體人。
          • 2、Ik 詞典main.dic 非原生,做了互聯(lián)網(wǎng)詞庫的擴展,但詞庫中依然沒有“劉強東”三個字。
          • 3、如果你在本地測試結果和文章不一致,極大可能是詞典不一樣導致的。
          PUT test-004
          {
            "mappings": {
              "properties": {
                "title": {
                  "type""text",
                  "analyzer""ik_max_word",
                  "fields": {
                    "keyword": {
                      "type""keyword"
                    }
                  }
                }
              }
            }
          }

          POST test-004/_bulk
          {"index":{"_id":1}}
          {"title":"英文官網(wǎng)承認劉強東一度被捕的原因是涉嫌XX"}
          {"index":{"_id":2}}
          {"title":"別提了朋友哥哥劉強東窗事發(fā)了"}
          {"index":{"_id":3}}
          {"title":"劉強東施效顰,沒想到竟然收獲了流量"}
          {"index":{"_id":4}}
          {"title":"劉強東是誰?我不認識"}


          POST test-004/_search
          {
            "query": {
              "match_phrase": {
                "title""劉強東"
              }
            }
          }

          用的短語檢索 match_phrase,搜索結果如下:

          原因說明,analyzer API 能說明一切。

          POST test-004/_analyze
          {
            "text": [
              "京東英文官網(wǎng)承認劉強東一度被捕的原因是涉嫌XX"
            ],
            "analyzer""ik_max_word"
          }

          分詞結果如下:

          面對如上召回情況,部分不追求精準率只追求召回率的業(yè)務場景,可能會需要文檔_id = 1、2、3、4 全部都要召回。

          這時候,如果不改變分詞的情況下,可能的解決方案之一就是:wildcard 檢索實現(xiàn)。

          POST test-004/_search
          {
            "query": {
              "wildcard": {
                "title.keyword""*劉強東*"
              }
            }
          }

          如上的方式,文檔1、2、3、4全部召回。

          相當于在原有DSL的基礎上,只改動檢索方式和字段名稱就搞定了產(chǎn)品經(jīng)理的提高召回率的需求。

          貌似,可以交差大吉了。實則,有非常大的隱患。

          4、wildcard 可能的風險

          官方文檔是這么說的:

          中文含義是:避免以*或?開頭的模式。這會增加查找匹配項所需的迭代次數(shù)并降低搜索性能。

          wildcard 到底有多慢?如下示例可見一斑:

          wildcard 檢索字段指定的字符數(shù)多了以后,會報錯如下:

          在 wood 大叔 2017年的文章中,曾經(jīng)指出如下的核心點:

          • 4.1 出現(xiàn)問題

          用戶輸入的字符串長度沒有做限制,導致首尾通配符中間可能是很長的一個字符串。后果就是對應的wildcard Query執(zhí)行非常慢,非常消耗CPU。

          • 4.2 根本原因

          為了加速通配符和正則表達式的匹配速度,Lucene4.0開始會將輸入的字符串模式構建成一個DFA (Deterministic Finite Automaton),帶有通配符的pattern構造出來的DFA可能會很復雜,開銷很大。

          源碼及細節(jié)推薦閱讀:

          https://elasticsearch.cn/article/171

          https://elasticsearch.cn/article/186

          5、wildcard 實戰(zhàn)中的悲劇

          如下,采用原汁原味的技術群交流內(nèi)容,更具有說服力。

          更能警示大家:慎用 Wildcard!

          5.1 悲劇1:一味的滿足產(chǎn)品經(jīng)理的需求,wildcard 不考慮性能的亂用。


          5.2 悲劇2:wildcard 參數(shù)傳了一篇文章進來,導致集群宕機!

          5.3 悲劇3:wildcard 搜索一百個漢字,導致CPU利用率 100%!

          注意是:不同100個字組合,一直搜。

          5.4 悲劇4:客戶現(xiàn)場演示,集群宕機!

          根因:bool 組合了近 100 組+ wildcard 不同關鍵詞的檢索。

          6、wildcard 可能的替代方案

          在尋求解決方案的時候,我們要先問一下:為什么大家喜歡用 wildcard 實現(xiàn)模糊檢索?

          得到的答復往往是:順手,類似Mysql like 查詢,短、平、快的達到了產(chǎn)品經(jīng)理的要求,滿足了項目需求。

          但,這忽略了性能問題以及可能帶來的災難后果。

          所以,解決方案應該從根源上入手,以尋求徹底解決。

          6.1 替代方案一:寫入時分詞優(yōu)化,使用 Ngram 分詞。

          更細粒度分詞,更有利于數(shù)據(jù)的召回!

          PUT test-005
          {
            "settings": {
              "index.max_ngram_diff": 10,
              "analysis": {
                "analyzer": {
                  "my_analyzer": {
                    "tokenizer""my_tokenizer"
                  }
                },
                "tokenizer": {
                  "my_tokenizer": {
                    "type""ngram",
                    "min_gram": 3,
                    "max_gram": 10,
                    "token_chars": [
                      "letter",
                      "digit"
                    ]
                  }
                }
              }
            },
            "mappings": {
              "properties": {
                "title": {
                  "type""text",
                  "analyzer""my_analyzer",
                  "fields": {
                    "keyword": {
                      "type""keyword"
                    }
                  }
                }
              }
            }
          }

          POST test-005/_bulk
          {"index":{"_id":1}}
          {"title":"英文官網(wǎng)承認劉強東一度被捕的原因是涉嫌性侵"}
          {"index":{"_id":2}}
          {"title":"別提了朋友哥哥劉強東窗事發(fā)了"}
          {"index":{"_id":3}}
          {"title":"劉強東施效顰,沒想到竟然收獲了流量"}
          {"index":{"_id":4}}
          {"title":"劉強東是誰?我不認識"}

          POST test-005/_search
          {
            "query": {
              "match_phrase": {
                "title""劉強東"
              }
            }
          }

          Ngram 實現(xiàn)推薦:

          Elasticsearch能檢索出來,但不能正確高亮怎么辦?

          6.2 替代方案二:7.9 + 以上的版本,使用 wildcard 數(shù)據(jù)類型。

          wildcard 類型出現(xiàn)的目的:一方面避免了某些場景下分詞查詢不準確的問題,另一方面也解決了通配符和正則檢索的效率問題。

          注意:新上的數(shù)據(jù)類型 wildcard,而非 wildcard 檢索。

          使用方法參見:

          https://www.elastic.co/guide/en/elasticsearch/reference/master/keyword.html#wildcard-field-type。

          6.3 禁用方案:禁止使用wildcard 模糊檢索

          特殊業(yè)務場景需要禁止:wildcard 檢索。

          實現(xiàn)如下:

          PUT _cluster/settings
          {
            "transient": {
              "search.allow_expensive_queries"false
            }
          }

          需要強調(diào)的是: 

          "search.allow_expensive_queries"  是 7.7+ 版本才有的功能,早期版本會報錯。

          7、小結

          由于技術慣性,我們習慣于相同或者相通技術的技術遷移,比如:mysql like 查詢遷移到 Elasticsearch 中的 wildcard 模糊檢索。但遷移的時候一定要注意:不同技術點的實現(xiàn)差異,同時要多關注技術點不能可能導致的性能問題。

          即便 2017年 wood 大叔就發(fā)了兩篇文章讓大家警惕 wildcard 模糊檢索可能帶來的性能問題。但四年后的今天,仍然很多公司的實戰(zhàn)業(yè)務中還未考慮性能及后果的前提下,樂此不疲的用著 wildcard 檢索!

          所以,本文算是 wood 大叔的 wildcard 警示文章接力,希望更多人看到。

          參考:

          https://t.zsxq.com/Y3zv7Eq 

          https://t.zsxq.com/bm62zZf



          推薦:

          1. 如何系統(tǒng)的學習 Elasticsearch ?

          2. 從實戰(zhàn)中來,到實戰(zhàn)中去——Elasticsearch 技能更快提升方法論

          3. 重磅 | 死磕 Elasticsearch 方法論認知清單(2020年國慶更新版)

          4. 探究 | 明明存在,怎么搜索不出來呢?


          中國最大的 Elastic 非官方公眾號

          更短時間更快習得更多干貨

          點擊查看“閱讀原文”,更短時間更快習得更多干貨。和全球 1000 位+ Elastic 愛好者(含中國 50%+ Elastic 認證工程師)一起每日精進 ELK 技能!

          瀏覽 85
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产无遮挡又黄又爽又 | 欧美精品一区二区三区免费久久久 | 日本靠逼网站 | 台湾无码免费电影 | 亚洲一级操逼 |