Elasticsearch 分詞器

在全文搜索(Fulltext Search)中,詞(Term)是一個搜索單元,表示文本中的一個詞,標(biāo)記(Token)表示在文本字段中出現(xiàn)的詞,由詞的文本、在原始文本中的開始和結(jié)束偏移量、以及數(shù)據(jù)類型等組成。ElasticSearch 把文檔數(shù)據(jù)寫到倒排索引(Inverted Index)的結(jié)構(gòu)中,倒排索引建立詞(Term)和文檔之間的映射,索引中的數(shù)據(jù)是面向詞,而不是面向文檔的。分析器(Analyzer)的作用就是分析(Analyse),用于把傳入Lucene的文檔數(shù)據(jù)轉(zhuǎn)化為倒排索引,把文本處理成可被搜索的詞。

在ElasticSearch引擎中,分析器的任務(wù)是分析(Analyze)文本數(shù)據(jù),分析是分詞,規(guī)范化文本的意思,其工作流程是:

  1. 首先,字符過濾器對分析(analyzed)文本進行過濾和處理,例如從原始文本中移除HTML標(biāo)記,根據(jù)字符映射替換文本等,

  2. 過濾之后的文本被分詞器接收,分詞器把文本分割成標(biāo)記流,也就是一個接一個的標(biāo)記,

  3. 然后,標(biāo)記過濾器對標(biāo)記流進行過濾處理,例如,移除停用詞,把詞轉(zhuǎn)換成其詞干形式,把詞轉(zhuǎn)換成其同義詞等,

  4. 最終,過濾之后的標(biāo)記流被存儲在倒排索引中;

  5. ElasticSearch引擎在收到用戶的查詢請求時,會使用分析器對查詢條件進行分析,根據(jù)分析的結(jié)構(gòu),重新構(gòu)造查詢,以搜索倒排索引,完成全文搜索請求。

無論是內(nèi)置的分析器(analyzer),還是自定義的分析器(analyzer),都由三種構(gòu)件塊組成的:**character filters ,tokenizers **和 token filters。

  • **character filters **

    字符過濾器以字符流的形式接收原始文本,并可以通過添加、刪除或更改字符來轉(zhuǎn)換該流。

    舉例來說,一個字符過濾器可以用來把阿拉伯?dāng)?shù)字(??????????)轉(zhuǎn)成成Arabic-Latin的等價物(0123456789)。

    一個分析器可能有0個或多個字符過濾器,它們按順序應(yīng)用。

  • Tokenizer (分詞器)

    一個分詞器接收一個字符流,并將其拆分成單個token (通常是單個單詞),并輸出一個token流。例如,一個whitespace分詞器當(dāng)它看到空白的時候就會將文本拆分成token。它會將文本“Quick brown fox!”轉(zhuǎn)換為[Quick, brown, fox!]

    (PS:Tokenizer 負責(zé)將文本拆分成單個token ,這里token就指的就是一個一個的單詞。就是一段文本被分割成好幾部分 )

    分詞器還負責(zé)記錄每個term的順序或位置,以及該term所表示的原單詞的開始和結(jié)束字符偏移量。(PS:文本被分詞后的輸出是一個term數(shù)組)

    一個分析器必須只能有一個分詞器

  • Token filters (token過濾器)

    token過濾器接收token流,并且可能會添加、刪除或更改tokens。

    例如,一個lowercase token filter可以將所有的token轉(zhuǎn)成小寫。stop token filter可以刪除常用的單詞,比如 the 。synonym token filter可以將同義詞引入token流。

    不允許token過濾器更改每個token的位置或字符偏移量。

    一個分析器可能有0個或多個token過濾器,它們按順序應(yīng)用。

ES內(nèi)置分詞器(Tokenizer)

分詞器在字符過濾器之后工作,用于把文本分割成多個標(biāo)記(Token),一個標(biāo)記基本上是詞加上一些額外信息,分詞器的處理結(jié)果是標(biāo)記流,它是一個接一個的標(biāo)記,準備被過濾器處理。

  • 標(biāo)準分析器(Standard)

    分析器類型是standard,由標(biāo)準分詞器(Standard Tokenizer),標(biāo)準標(biāo)記過濾器(Standard Token Filter),小寫標(biāo)記過濾器(Lower Case Token Filter)和停用詞標(biāo)記過濾器(Stopwords Token Filter)組成。參數(shù)stopwords用于初始化停用詞列表,默認是空的。

  • 簡單分析器(Simple)

    分析器類型是simple,實際上是小寫標(biāo)記分詞器(Lower Case Tokenizer),在非字母位置上分割文本,并把分詞轉(zhuǎn)換為小寫形式,功能上是Letter Tokenizer和 Lower Case Token Filter的結(jié)合(Combination),但是性能更高,一次性完成兩個任務(wù)。

  • 空格分析器(Whitespace)

    分析器類型是whitespace,實際上是空格分詞器(Whitespace Tokenizer)。

  • 停用詞分析器(Stopwords)

    分析器類型是stop,由小寫分詞器(Lower Case Tokenizer)和停用詞標(biāo)記過濾器(Stop Token Filter)構(gòu)成,配置參數(shù)stopwords或 stopwords_path指定停用詞列表。

  • 雪球分析器(Snowball)

    分析器類型是snowball,由標(biāo)準分詞器(Standard Tokenizer),標(biāo)準過濾器(Standard Filter),小寫過濾器(Lowercase Filter),停用詞過濾器(Stop Filter)和雪球過濾器(Snowball Filter)構(gòu)成。參數(shù)language用于指定語言。

  • 自定義分析器

    分析器類型是custom,允許用戶定制分析器。參數(shù)tokenizer 用于指定分詞器,filter用于指定過濾器,char_filter用于指定字符過濾器。

內(nèi)置分析器實例

這里我們使用的工具是Kibana,我們在這里來操作一下Elasticsearch。如下的事例是ES默認的標(biāo)準分析器,我們使用_analyze來調(diào)試實驗一下。

POST _analyze
{
    "analyzer": "standard",
    "text": "I am Chinese."
}

輸出如下結(jié)果:

{
  "tokens" : [
    {
      "token" : "i",
      "start_offset" : 0,
      "end_offset" : 1,
      "type" : "<ALPHANUM>",
      "position" : 0
    },
    {
      "token" : "am",
      "start_offset" : 2,
      "end_offset" : 4,
      "type" : "<ALPHANUM>",
      "position" : 1
    },
    {
      "token" : "chinese",
      "start_offset" : 5,
      "end_offset" : 12,
      "type" : "<ALPHANUM>",
      "position" : 2
    }
  ]
}

而使用空格分析器的話,就會對每個空格進行分割,如下

POST _analyze
{
  "analyzer": "whitespace",
  "text": "I'm Chinese."
}

輸出結(jié)果:

{
  "tokens" : [
    {
      "token" : "I'm",
      "start_offset" : 0,
      "end_offset" : 3,
      "type" : "word",
      "position" : 0
    },
    {
      "token" : "Chinese.",
      "start_offset" : 4,
      "end_offset" : 12,
      "type" : "word",
      "position" : 1
    }
  ]
}

接下來我們創(chuàng)建一個自定義分析器:

# 創(chuàng)建一個自定義分詞器
PUT test_index_1
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_custom_anaylzer" : {
          "type" : "custom",
          "tokenizer" : "standard",
          "char_filter" : ["html_strip"],
          "filter" : ["lowercase"]
        }
      }
    }
  }
}

以上代碼是創(chuàng)建一個自定義分析器,其中使用分析器是標(biāo)準分析器,字符串過濾使用的是html_strip(去除里面的html標(biāo)簽內(nèi)容),token過濾器用的是lowercase,也就是把取出來的字符都轉(zhuǎn)成小寫。運行如下事例。

POST test_index_1/_analyze
{
  "analyzer" : "my_custom_anaylzer",
  "text" : "Is this <b> a box <b>?"
}

輸出結(jié)果為:

{
  "tokens" : [
    {
      "token" : "is",
      "start_offset" : 0,
      "end_offset" : 2,
      "type" : "<ALPHANUM>",
      "position" : 0
    },
    {
      "token" : "this",
      "start_offset" : 3,
      "end_offset" : 7,
      "type" : "<ALPHANUM>",
      "position" : 1
    },
    {
      "token" : "a",
      "start_offset" : 12,
      "end_offset" : 13,
      "type" : "<ALPHANUM>",
      "position" : 2
    },
    {
      "token" : "box",
      "start_offset" : 14,
      "end_offset" : 17,
      "type" : "<ALPHANUM>",
      "position" : 3
    }
  ]
}

參考

https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis.html

https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-tokenfilters.html

https://github.com/medcl/elasticsearch-analysis-ik

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容