Elasticsearch分析器

Elasticsearch分析器

無(wú)論是內(nèi)置的分析器(analyzer)屑埋,還是自定義的分析器(analyzer)咪笑,都是由字符過(guò)濾器(character filters)上鞠、分詞器(tokenizers) 和 token過(guò)濾器( token filters)組成妓羊。char_filter是字符過(guò)濾器驾讲,filter是token filter郎仆。

字符過(guò)濾器(character filters)
  • 字符過(guò)濾器以字符流的形式接受原始文本只祠,并可以通過(guò)增加、刪除和更改字符來(lái)轉(zhuǎn)換字符流扰肌。分詞之前預(yù)處理抛寝。

  • 一個(gè)analyzer可以有0個(gè)或者多個(gè)character filters。

  • HTML字符過(guò)濾器(HTML Strip Character Filter): html_strip表示提出html標(biāo)簽曙旭;escaped_tags表示保留html標(biāo)簽盗舰。

    # my_char_filter:自定義char_filter,剔除除<a>標(biāo)簽外的所有的html標(biāo)簽
    # tokenizer:keyword  keyword分詞器:整個(gè)輸入作為一個(gè)單獨(dú)詞匯單元桂躏,方便特殊類型的文本進(jìn)行索引和檢索钻趋。針對(duì)郵政編碼,地址等文本信息使用關(guān)鍵詞分詞器進(jìn)行索引項(xiàng)建立非常方便
    # my_analyzer:自定義分析器
      
    DELETE my_index
    PUT my_index
    {
    "settings": {
      "analysis": {
        "char_filter": {
          "my_char_filter":{
            "type":"html_strip",
            "escaped_tags": ["a"]
          }
        }
        , "analyzer": {
          "my_analyzer":{
            "tokenizer":"keyword",
            "char_filter":"my_char_filter"
          }
        }
      }
    }
    }
    
    POST my_index/_analyze
    {
    "analyzer": "my_analyzer",
    "text": "<p>I&apos;m so <a>happy</a>!</p>"
    }
    
    {
    "tokens" : [
      {
        // 過(guò)濾之后的結(jié)果  
        "token" : """
    I'm so <a>happy</a>!
    """,
        "start_offset" : 0,
        "end_offset" : 32,
        "type" : "word",
        "position" : 0
      }
    ]
    }
    
  • 映射字符過(guò)濾器(Mapping Character Filter): type -> mapping 字符映射

    # my_char_filter:自定義char_filter剂习,利用type=mapping進(jìn)行字符替換
    # tokenizer:keyword  keyword分詞器:整個(gè)輸入作為一個(gè)單獨(dú)詞匯單元蛮位,方便特殊類型的文本進(jìn)行索引和檢索。針對(duì)郵政編碼鳞绕,地址等文本信息使用關(guān)鍵詞分詞器進(jìn)行索引項(xiàng)建立非常方便
    # my_analyzer:自定義分析器
      
    DELETE my_index
    PUT my_index
    {
    "char_filter": {
        "my_char_filter": {
            "type": "mapping",
            "mappings": [
                "? => 0",
                "? => 1",
                "? => 2",
                "? => 3",
                "? => 4",
                "? => 5",
                "? => 6",
                "? => 7",
                "? => 8",
                "? => 9"
            ]
        }
    },
    "settings": {
        "analysis": {
            "analyzer": {
                "my_analyzer": {
                    "tokenizer": "keyword",
                    "char_filter": [
                        "my_char_filter"
                    ]
                }
            }
    
        }
    }
    }
    POST my_index/_analyze
    {
    "analyzer": "my_analyzer",
    "text": "My license plate is ?????"
    }
    
    {
    "tokens" : [
      {
        "token" : "My license plate is 25015",
        "start_offset" : 0,
        "end_offset" : 25,
        "type" : "word",
        "position" : 0
      }
    ]
    }
    
  • 模式替換過(guò)濾器(Patten Replace Character Filter): type -> patten_replace 正則匹配

    DELETE my_index
    # my_analyzer:自定義模式匹配分析器失仁,正則匹配上的字符串將不再分詞
    PUT my_index
    {
    "settings": {
      "analysis": {
        "analyzer": {
          "my_analyzer": {
            "tokenizer": "standard",
            "char_filter": ["my_char_filter"]
          }
        },
        "char_filter": {
          "my_char_filter": {
            "type": "pattern_replace",
            "pattern": "(\\d+)-(?=\\d)",
            "replacement": "$1_"
          }
        }
      }
    }
    }
    
    POST my_index/_analyze
    {
    "analyzer": "my_analyzer",
    "text": "My credit card is 123-456-789"
    }
    
    {
    "tokens" : [
      {
        "token" : "My",
        "start_offset" : 0,
        "end_offset" : 2,
        "type" : "<ALPHANUM>",
        "position" : 0
      },
      {
        "token" : "credit",
        "start_offset" : 3,
        "end_offset" : 9,
        "type" : "<ALPHANUM>",
        "position" : 1
      },
      {
        "token" : "card",
        "start_offset" : 10,
        "end_offset" : 14,
        "type" : "<ALPHANUM>",
        "position" : 2
      },
      {
        "token" : "is",
        "start_offset" : 15,
        "end_offset" : 17,
        "type" : "<ALPHANUM>",
        "position" : 3
      },
      {
        "token" : "123_456_789",
        "start_offset" : 18,
        "end_offset" : 29,
        "type" : "<NUM>",
        "position" : 4
      }
    ]
    }
    
分詞器(Tokenizer)
  • 一個(gè)分詞器接受一個(gè)字符流,并將其拆分成單個(gè)token(通常是單個(gè)單詞)们何,并輸出一個(gè)token流萄焦。

  • Tokenizer負(fù)責(zé)將文本拆分成單個(gè)token(一個(gè)一個(gè)的單詞,這些單詞叫token)冤竹,就是一段文本被分隔成好幾部分拂封,相當(dāng)于java的split。

  • 分詞器負(fù)責(zé)記錄每個(gè)term的書(shū)序或位置鹦蠕,以及term所表示的原單詞的開(kāi)始和結(jié)束字符偏移量(文本被分詞后的輸出是一個(gè)term數(shù)組)冒签。

  • 一個(gè)分析器必須只能一個(gè)分詞器

  • ES內(nèi)置分詞器 7.6 15種 自帶分詞器
    ① standard analyzer:默認(rèn)分詞器,中文支持的不理想钟病,會(huì)逐字拆分萧恕。
    1) max_token_length:最大令牌長(zhǎng)度霜定。如果看到令牌超過(guò)此長(zhǎng)度,則將其max_token_length間隔分割廊鸥。默認(rèn)為255望浩。
    ② Pattern Tokenizer:以正則匹配分隔符,把文本拆分成若干詞項(xiàng)惰说。
    ③ Simple Pattern Tokenizer:以正則匹配詞項(xiàng)磨德,速度比Pattern Tokenizer快。
    ④ whitespace analyzer:以空白符分隔 Tim_cookie

  • 代碼樣例:

    #設(shè)置type為custom告訴Elasticsearch我們正在定義一個(gè)定制分析器吆视。將此與配置內(nèi)置分析器的方式進(jìn)行比較: type將設(shè)置為內(nèi)置分析器的名稱典挑,如 standard或simple
    
    # 自定義字符過(guò)濾器 test_char_filter ,將 & 替換為 and | 替換為 or
    # 自定義token filter啦吧, 停用詞 is您觉、in、at授滓、the琳水、a、for
    # 分詞器增加標(biāo)點(diǎn)過(guò)濾:模式匹配般堆,去除 .,!? 四種標(biāo)點(diǎn)符號(hào)    
    # 自定義分析器 my_analyzer 匯總以上三種自定義在孝,同時(shí)character filter增加提出html,token  filter 增加 字母小寫(xiě)淮摔。    
    PUT /test_analysis
    {
    "settings": {
      "analysis": {
        "char_filter": {
          "test_char_filter": {
            "type": "mapping",
            "mappings": [
              "& => and",
              "| => or"
            ]
          }
        },
        "filter": {
          "test_stopwords": {
            "type": "stop",
            "stopwords": ["is","in","at","the","a","for"]
          }
        },
        "tokenizer": {
          "punctuation": { 
            "type": "pattern",
            "pattern": "[ .,!?]"
          }
        },
        "analyzer": {
          "my_analyzer": {
            "type": "custom",
            "char_filter": [
              "html_strip",
              "test_char_filter"
            ],
            "tokenizer": "standard",
            "filter": ["lowercase","test_stopwords"]
          }
        }
      }
    }
    }
    
    GET /test_analysis/_analyze
    {
    "text": "Teacher ma & zhang also thinks [mother's friends] is good | nice!!!",
    "analyzer": "my_analyzer"
    }
    
    # 執(zhí)行結(jié)果
    {
    "tokens" : [
      {
        "token" : "teacher",
        "start_offset" : 0,
        "end_offset" : 7,
        "type" : "<ALPHANUM>",
        "position" : 0
      },
      {
        "token" : "ma",
        "start_offset" : 8,
        "end_offset" : 10,
        "type" : "<ALPHANUM>",
        "position" : 1
      },
      {
        "token" : "and",
        "start_offset" : 11,
        "end_offset" : 12,
        "type" : "<ALPHANUM>",
        "position" : 2
      },
      {
        "token" : "zhang",
        "start_offset" : 13,
        "end_offset" : 18,
        "type" : "<ALPHANUM>",
        "position" : 3
      },
      {
        "token" : "also",
        "start_offset" : 19,
        "end_offset" : 23,
        "type" : "<ALPHANUM>",
        "position" : 4
      },
      {
        "token" : "thinks",
        "start_offset" : 24,
        "end_offset" : 30,
        "type" : "<ALPHANUM>",
        "position" : 5
      },
      {
        "token" : "mother's",
        "start_offset" : 32,
        "end_offset" : 40,
        "type" : "<ALPHANUM>",
        "position" : 6
      },
      {
        "token" : "friends",
        "start_offset" : 41,
        "end_offset" : 48,
        "type" : "<ALPHANUM>",
        "position" : 7
      },
      {
        "token" : "good",
        "start_offset" : 53,
        "end_offset" : 57,
        "type" : "<ALPHANUM>",
        "position" : 9
      },
      {
        "token" : "or",
        "start_offset" : 58,
        "end_offset" : 59,
        "type" : "<ALPHANUM>",
        "position" : 10
      },
      {
        "token" : "nice",
        "start_offset" : 60,
        "end_offset" : 64,
        "type" : "<ALPHANUM>",
        "position" : 11
      }
    ]
    }    
    
Token過(guò)濾器(token filters)
  • token filters接受token流私沮,并且可能會(huì)增加、刪除或者更改token流和橙;

  • 不允許token過(guò)濾器更改每個(gè)token的位置和字符偏移仔燕。

  • 一個(gè)分詞器可能有0個(gè)或者多個(gè)token過(guò)濾器,它們按照順序應(yīng)用魔招。

  • 一般負(fù)責(zé)時(shí)態(tài)轉(zhuǎn)換晰搀、大小寫(xiě)轉(zhuǎn)換、同義詞轉(zhuǎn)換仆百、語(yǔ)氣詞處理等厕隧。比如 has=>have him=>he apples=>apple the/oh/a=>干掉

  • 代碼樣例-1:

    DELETE my_index
    # setting 設(shè)置索引配置
    # my_token_filter:自定義token過(guò)濾器奔脐,1~20個(gè)字符詞條才會(huì)被搜索  
    # my_analyzer:自定義分析器俄周;使用的token過(guò)濾器有:lowercase(系統(tǒng))  和 my_token_filter(自定義) 
    # type:custom 固定寫(xiě)法,表示自定義分析器
    # tokenizer:standard 系統(tǒng)自帶的分詞器髓迎。
    # mappings中定義字段映射峦朗,使用自定義的分析器。
    # analyzer 指的是在建索引時(shí)的分詞策略
    # search_analyzer 指的是在查詢時(shí)的分詞策略    
      
    PUT my_index
    {
    "settings": {
      "analysis": {
        "filter": {
          "my_token_filter":{
            "type":"edge_ngram",
            "min_gram":1,
            "max_gram":20
          }
        }
        , "analyzer": {
          "my_analyzer":{
            "type":"custom",
            "tokenizer":"standard",
            "filter":[
              "lowercase",
              "my_token_filter"
            ]
          }
        }
      }
    }
    , "mappings": {
      "properties": {
        "keyword":{
          "type": "text"
          , "analyzer": "my_analyzer"
          , "search_analyzer": "standard"
        }
      }
    }
    }
    
  • 代碼樣例-2:

    # 利用stardard 將文本分詞之后的所有token進(jìn)行小寫(xiě)排龄。
    GET _analyze
    {
    "tokenizer" : "standard",
    "filter" : ["lowercase"],
    "text" : "THE Quick FoX JUMPs"
    }
    
    # 自定義條件token過(guò)濾器
    GET /_analyze
    {
    "tokenizer":"standard",
    "filter": [
      {
        "type": "condition",
        "filter": [
          "lowercase"
        ],
        "script": {
          "source": "token.getTerm().length() < 5"
        }
      }
    ],
    "text": "THE QUICK BROWN FOX"
    }
    
  • 代碼樣例-3:

    # 自定義分析器波势,采用英語(yǔ)內(nèi)置的stopword(停用詞)
    PUT /my_index
    {
    "settings": {
      "analysis": {
        "analyzer": {
          "my_analyzer":{
            "type":"standard",
            "stopwords":"_english_"
          }
        }
      }
    }
    }
    GET my_index/_analyze
    {
    "analyzer": "my_analyzer",
    "text": "Teacher Ma is in the restroom"
    }
    

停用詞:

  • 停用詞過(guò)濾:是文本分析中一個(gè)預(yù)處理方法。它的功能是過(guò)濾分詞結(jié)果中的噪聲(例如:的、是尺铣、啊等)

  • 停用詞:指在信息檢索中拴曲,為節(jié)省存儲(chǔ)空間和提高搜索效率,在處理自然語(yǔ)言數(shù)據(jù)(或文本)之前或之后會(huì)自動(dòng)過(guò)濾掉某些字或詞凛忿,這些字或詞即被稱為Stop Words(停用詞)澈灼。這些停用詞都是人工輸入、非自動(dòng)化生成的店溢,生成后的停用詞會(huì)形成一個(gè)停用詞表叁熔。但是,并沒(méi)有一個(gè)明確的停用詞表能夠適用于所有的工具床牧。甚至有一些工具是明確地避免使用停用詞來(lái)支持短語(yǔ)搜索的荣回。

  • 移除停用詞的工作是由stop停用詞過(guò)濾器完成的,可以通過(guò)創(chuàng)建自定義分析器來(lái)使用它戈咳。但是也有一些自帶的分析器預(yù)制使用停用詞過(guò)濾器

  • 語(yǔ)言分析器:每個(gè)語(yǔ)言分析器默認(rèn)使用 該語(yǔ)言相適應(yīng)的停用詞列表心软。特定語(yǔ)言的默認(rèn)停用詞,可以通過(guò)使用 _lang_ 符號(hào)來(lái)指定著蛙。如 english 英語(yǔ)分析器使用 :_english_ 停用詞列表糯累。"stopwords": "_english_";

    # 默認(rèn)的停用詞是 _english_
    # 本例通過(guò) _none_ 禁用了停用詞    
    PUT /my_index
    {
    "settings": {
      "analysis": {
        "analyzer": {
          "my_english": {
            "type":      "english", 
            "stopwords": "_none_" 
          }
        }
      }
    }
    }
    # 停用詞 可以指定路徑
    # 停用詞文件的路徑册踩,該路徑相對(duì)于 Elasticsearch 的 config 目錄    
    PUT /my_index
    {
    "settings": {
      "analysis": {
        "analyzer": {
          "my_english": {
            "type":           "english",
            "stopwords_path": "stopwords/english.txt" 
          }
        }
      }
    }
    }
    
  • standard 標(biāo)準(zhǔn)分析器:默認(rèn)使用空的停用詞列表:_none_泳姐,實(shí)際是禁用了停用詞。

    # 自定義分析器 my_analyzer
    # 標(biāo)準(zhǔn)的standard分析器暂吉,進(jìn)行了一些自定義配置
    # 過(guò)濾掉停用詞 and 和 the    
    PUT /my_index
    {
    "settings": {
      "analysis": {
        "analyzer": {
          "my_analyzer": { 
            "type": "standard", 
            "stopwords": [ "and", "the" ] 
          }
        }
      }
    }
    }
    
  • pattern模式分析器:與standard分析器類似胖秒,默認(rèn)使用空的的停用詞里誒博愛(ài):為_(kāi)none_。

分詞器(analyzer)處理過(guò)程

分詞器處理過(guò)程.jpg

搜索引擎的人性化(Normalization)

為key_words提供更加完整的倒排索引慕的。

如:時(shí)態(tài)轉(zhuǎn)化(like | liked)阎肝,單復(fù)數(shù)轉(zhuǎn)化(man | men),全寫(xiě)簡(jiǎn)寫(xiě)(china | cn)肮街,同義詞(small | little)等风题。

如:china 搜索時(shí),如果條件為cn是否可搜索到嫉父。

如:dogs沛硅,搜索時(shí),條件為dog是否可搜索到數(shù)據(jù)绕辖。

如果可以使用簡(jiǎn)寫(xiě)(cn)或者單復(fù)數(shù)(dog&dogs)搜索到想要的結(jié)果摇肌,那么稱為搜索引擎normalization人性化。

normalization是為了提升召回率的(recall)仪际,就是提升搜索能力的围小。

normalization是配合分詞器(analyzer)完成其功能的昵骤。

分詞器的功能就是處理Document中的field的。就是創(chuàng)建倒排索引過(guò)程中用于切分field數(shù)據(jù)的肯适。

如:I think dogs is human’s best friend.在創(chuàng)建倒排索引的時(shí)候变秦,使用分詞器實(shí)現(xiàn)數(shù)據(jù)的切分。

上述的語(yǔ)句切分成若干的詞條框舔,分別是: think dog human best friend伴栓。

常見(jiàn)搜索條件有:think、 human雨饺、 best钳垮、 friend,很少使用is额港、a饺窿、the、i這些數(shù)據(jù)作為搜索條件移斩。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末肚医,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子向瓷,更是在濱河造成了極大的恐慌肠套,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,817評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件猖任,死亡現(xiàn)場(chǎng)離奇詭異你稚,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)朱躺,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門刁赖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人长搀,你說(shuō)我怎么就攤上這事宇弛。” “怎么了源请?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,354評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵枪芒,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我谁尸,道長(zhǎng)舅踪,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,498評(píng)論 1 284
  • 正文 為了忘掉前任症汹,我火速辦了婚禮硫朦,結(jié)果婚禮上贷腕,老公的妹妹穿的比我還像新娘背镇。我一直安慰自己咬展,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,600評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布瞒斩。 她就那樣靜靜地躺著破婆,像睡著了一般。 火紅的嫁衣襯著肌膚如雪胸囱。 梳的紋絲不亂的頭發(fā)上祷舀,一...
    開(kāi)封第一講書(shū)人閱讀 49,829評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音烹笔,去河邊找鬼裳扯。 笑死,一個(gè)胖子當(dāng)著我的面吹牛谤职,可吹牛的內(nèi)容都是我干的饰豺。 我是一名探鬼主播,決...
    沈念sama閱讀 38,979評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼允蜈,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼冤吨!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起饶套,我...
    開(kāi)封第一講書(shū)人閱讀 37,722評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤漩蟆,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后妓蛮,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體怠李,經(jīng)...
    沈念sama閱讀 44,189評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,519評(píng)論 2 327
  • 正文 我和宋清朗相戀三年蛤克,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了扔仓。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,654評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡咖耘,死狀恐怖翘簇,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情儿倒,我是刑警寧澤版保,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站夫否,受9級(jí)特大地震影響彻犁,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜凰慈,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,940評(píng)論 3 313
  • 文/蒙蒙 一汞幢、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧微谓,春花似錦森篷、人聲如沸输钩。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,762評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)买乃。三九已至,卻和暖如春钓辆,著一層夾襖步出監(jiān)牢的瞬間剪验,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,993評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工前联, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留功戚,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,382評(píng)論 2 360
  • 正文 我出身青樓似嗤,卻偏偏與公主長(zhǎng)得像疫铜,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,543評(píng)論 2 349