Elasticsearch---分析器(analysis)

Elasticsearch---分析(analysis)

    ES 的倒排索引即是根据分词后的单词创建,意味着在搜索的时候,匹配分词后的单词才能命中该文档。

一、倒排序简介:

二、用到analysis的地方:

1. 写时分词:发生在写入、更新文档时,由analysis经过分析由Tokens列表,将结果存入倒排索引。

2.读时分词: 发生在用户查询时,输入的关键词进行分词,分词结果只存在内存中。

 

二、ES分词流程:

Character filter-->>Tokenizer-->>Token filters

分析器(Analyzer)由三部分构成:

  • 0个或多个字符过滤器( Character filters)按顺序应用。
  • 有且只有一个分词器(Tokenizer)
  • 0个或多个过滤器(Token filters),按顺序应用。

1. 字符过滤器( Character filters)

字符过滤器以字符流的形式接收原始文本,并可以通过添加、删除或更改字符来转换该流。

Elasticearch只提供了三种字符过滤器:

  • HTML字符过滤器(HTML Strip Char Filter):文本中去除HTML元素。
  • 映射字符过滤器(Mapping Char Filter):映射仠替换。("mappings":["苍井空 => 666","武藤兰 => 888"])
  • 模式替换过滤器(Pattern Replace Char Filter):正则表达式匹配并替换,小心导致性能变慢
过滤器 简称 描述 支持参数
HTML Strip Char Filter html_strip 去除HTML元素 escaped_tags(排除的标签数组)
Mapping Char Filter mapping 根据配置的映射配置 mappings_path(一个key => value特定格式的文件路径,相对或config文件夹)
Pattern Replace Char Filter pattern_replace 使用java正则替换 pattern,replacement,flags

    参考详情见:

1. https://www.cnblogs.com/Neeo/articles/10613612.html

2. https://yuanwenjian.github.io/2018/03/09/Elasticsearch%E5%86%85%E7%BD%AE%E5%88%86%E8%AF%8D%E5%99%A8%E5%8F%8A%E5%AD%97%E7%AC%A6%E8%BF%87%E6%BB%A4%E5%99%A8/

 

2.分词器(Tokenizer):

一个分词器接收一个字符流,并将其拆分成单个token (通常是单个单词),并输出一个token流。

"text": "Is this déja vu?"---->Tokenizer----> tokens[...,...]  
token结构:
{
   "token":"The",   //term分词,用于倒排序。
   "start_offset":0, // 所有的字符串位置信息,高亮时用到。
   "end_offset":3,
   "type":"word",
   "position":0
  
}

ES内置分词器:

 1)标准分词器 Standard Tokenizer:

2)连词分词器 NGram Tokenizer

3)边际连词分词器 Edge NGram Tokenizer

4)关键字分词器 Keyword Tokenizer:不分词

5)字符分词器 Letter Tokenizer:将文本按非字符(non-lentter)进行分词

6)小写分词器 Lowercase Tokenizer:小写后,再按字符分词器 Letter Tokenizer

7)空格分词器Whitespace Tokenizer: 以空格来分词

8)模式分词器/正则分词器 Pattern Tokenizer

9)标准Email URL分词器 UAX Email URL Tokenizer:把email和url当作一个词

10)路径层次分词器 Path Hierarchy Tokenizer:按默认定界符: / ,路径分割

详情见:

1. https://jingyan.baidu.com/article/cbcede071e1b9e02f40b4d19.html

2. https://yuanwenjian.github.io/2018/03/10/Elasticsearch%E5%86%85%E7%BD%AE%E5%88%86%E6%9E%90%E5%99%A8/

中文分词器:

1)smartCN:一个简单的中文或中英文混合文本的分词器(官方提供)

2)IK分词器:目前比较流行的中文分词器之一,想要特别好的效果,需要自行维护词库,支持自定义词典。

3)结巴分词 : 有自行识别新词的功能,支持自定义词典

4)Ansj中文分词: 基于n-Gram+CRF+HMM的中文分词的java实现,免费开源,支持应用自然语言处理

5)hanlp: 免费开源,国人自然处理语言牛人无私风险的。

分词准确性从高到低依次是: hanlp> ansj >结巴>IK>Smart Chinese Analysis

3.Token过滤器(Token filters)

包含一个或多个,修改词(修改单词为小写),去掉词(连接词如"a”,“and”等),或者增加词(比如同义词)。处理后的结果称为索引词(Term),文档中包含几个这样的Term称为Frequency(词频 ).

es内置词元过滤器(Token Filter)

Token Filter 简称 描述 可支持参数
Standard standard standard 类型的词元过滤器规范化从 Standard Tokenizer(标准分词器)中提取的 tokens。什么也不做
ASCII Folding asciifolding 将不存在于ASCII中的字符转为ASCII字符 preserve_original
Flatten Graph flatten_graph 接受任意图形 token 流,例如由 Synonym Graph Token Filter 产生的图形 token 流,并将其平坦化为适用于索引的单个线性标记链
Length length 删除流中过长或过短的字词 min && max
Lowercase lowercase 小写过滤器
Uppercase uppercase 大写过滤器
NGram nGram min_gram && max_gram
Edge NGram edgeNGram min_gram && max_gram
Porter Stem porter_stem 无 tip:porter_stem限制输入必须为小写,所以之前使用lowercase货值lowercase Tokenizer
Shingle shingles 它创建词元的组合作为单个词元 max_shingle_size && min_shingle_size && output_unigrams && output_unigrams_if_no_shingles&& token_separator && filler_token
Stop stop 停词过滤器 stopwords && stopwords_path && ignore_case&& remove_trailing
Word Delimiter word_delimiter 将单词分解为子词 。。。
Word Delimiter Graph word_delimiter_graph    
Stemmer stemmer 通过单个统一接口提供(几乎)所有可用的词干词元过滤器的访问 name
Stemmer Override stemmer_override 通过应用自定义映射来覆盖词干算法,然后保护这些术语不被修改词干。 必须放置在任何词干过滤器之前 rules && rules_path
Keyword Marker keyword_marker 保护词语不被词干分析器修改。 必须放置在任何词干过滤器之前 keywords&& keywords_path &&keywords_pattern ignore_case
Keyword Repeat keyword_repeat 索引两边token,一个为原始,一个为词根,所以需要添加unique过滤器,并且设置only_on_same_position 为true
KStem kstem 用于英语的高性能过滤器
Snowball snowball 使用Snowball-generated 分词器 language
Phonetic phonetic analysis-phonetic 插件提供。
Synonym synonym 分析过程中轻松处理同义词。 同义词使用配置文件配置 synonyms_path && synonyms ignore_case && expand
Synonym Graph synonym_graph 实验版,
Compound Word hyphenation_decompounder \ dictionary_decompounder word_list && word_list_path &&min_word_size &&only_longest_match
Reverse reverse 将每个token反转
Elision elision 音节省略 articles 设置停用词
Truncate truncate 将token截取为固定长度 length 默认为10
Unique unique 在索引分析时仅索引唯一的token,默认为所有词条 only_on_same_position 设为true,只删除同一位置的token
Pattern Capture pattern_capture   preserve_original true返回原始token&& patterns
Pattern Replace pattern_replace 基于正则替换
Limit Token limit 限制每篇文档和字段索引的token数 max_token_count 默认为1 ;consume_all_tokens,如果为ture,超出限制也会最大程度处理token
Trim trim 去掉空白
Hunspell Token hunspell 用法暂时不明  
Common Grams common_grams 保留常用词语 common_grams; 常用词common_words_path;ignore_case;query_mode
Normalization      
CJK Width cjk_width    
CJK Bigram cjk_bigram    
Delimited Payload delimited_payload_filter 每当发现分隔符时,将标记分成标记和有效载荷。 delimiter 分隔符;encoding 负载类型
Keep Words keep 只保留具有预定义单词集中的文本的token keep_words保留列表;keep_words_path;keep_words_case 忽略大小写
Keep Types keep_types 只保留定义集合中的token types
Apostrophe apostrophe 过滤撇号后面字符,包括撇号
Classic classic 对Classic Tokenizer生成词元进行处理,从token删除后面所有权,删除省略符标点
Decimal Digit decimal_digit 将unicode数字转化为0-9
Fingerprint fingerprint 排序token,删除重复token,连接返回单个token separator;max_output_size 如果连接的指纹增长大于max_output_size ,则过滤器将退出并且不会发出token
Minhash min_hash 将token流中每个token一一哈希,并将生成的哈希值分成buckets,以保持每bucket最低值的散列值。 然后将这些哈希值作为token(词元)返回。minhash原理 hash_count;bucket_count

 

三、分词器设置:

 

1、更新分析器:

创建索引之后可以添加新的分析器,添加分析器之前必须关闭索引。

1) 关闭:POST / my-index/_close

(2) 更新:

方式一:PUT /my-index/_settings
{
    "analysis":{    
        "analyzer":{ //分析器列表
            "my_analyzer1":{ //自定义分析器名称 
                "type":"custom",     
                "char_filter": [ "emoticons"], //0或多个(可选)
                 "tokenizer": "punctuation", //有且只能有一个(必须有)
                  "filter": [ "lowercase", "english_stop"] //0或多个(可选)
                }
            "my_analyzer2":{ //自定义分析器名称 
                "type":"custom",     
                "char_filter": [ "emoticons"], 
                 "tokenizer": "punctuation", 
                  "filter": [ "lowercase", "english_stop"] 
                }
            }
        }       
    }
}​

方式二:PUT my-index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_english_analyzer": { //自定义分析器名称 
          "type": "standard",
          "max_token_length": 5,
          "stopwords": "_english_"
        }
      }
    }
  }
}

(3) 打开:POST /my-index/_open

 

2. 设置默认Analyzer(全局)

default:  是索引和搜索时用的默认的 analyzer,

default_index: 是索引时用的默认的 analyzer ,

 default_search:  是查询时用的默认analyzer。

操作方法: 内容填到elasticsearch/config/elasticsearch.yml中,之后重启elasticSearch(5.x 版本后,不能写在配置文件了,使用restApi来配置

 

3. 自定义Tokenizer和Filter,Char_filter

(1)设置索引分析器:

基本格式:
PUT / my-index  (以下设置只作用my-index索引)
{
    "settings": {
        "analysis": {
            "char_filter": { ... custom character filters ... },
            "tokenizer":   { ...    custom tokenizers     ... },
            "filter":      { ...   custom token filters   ... },
            "analyzer":    { ...    custom analyzers      ... }
        }
    }
}
实例:
PUT /my_index
{
"settings":{
    "analysis":{//自定义分词器的汇总
        //1.分析器定义列表
        "analyzer":{
            "myanalyzer":{
                "type":"custom",    //自定义分词器
                "tokenizer":"myTokenizer1",     //分解器别名,具体在下边定义
                "filter":["myTokenFilter1","myTokenFilter2"], //词元过滤器别名
                "char_filter":["my_html"],      //字符过滤器别名
                "position_increment_gap":256
            }
            "standard": {
                "type": "standard",
               "stop_words": [ "it", "is", "a" ]
            }
        }
    }
    //2.分词器定义列表
    "tokenizer":{       //具体定义分解器
        "myTokenizer1":{
            "type":"standard",
            "max_token_length":900
        }
    }
    //3.词元过滤器列表
    "filter":{      //具体定义词元过滤器
        "myTokenFilter1":{
            "type":"stop", //stop类型用于过滤掉对应的单词
            "stopwords":["stop1","stop2","stop3","stop4"], //该列表中的词都会被过滤掉
        },
        "myTokenFilter2":{
            "type":"length",
            "min":0,
            "max":2000
        }
    }
    //4. 字符过滤器列表
    "char_filter":{     //具体定义字符过滤器
        "my_html":{
            "type":"html_strip",
            "escaped_tags":[xxx,yyy],
            "read_ahead":1024
        }
    }
    }
}}

2. 在字段上使用自定义分析器:

PUT /my-index/_mapping/type
{"properties":{
    "title":{
        "type":"text",
        "analyzer":"my_analyzer"
    }
}}

 

posted @ 2021-11-23 14:00  游子善心  阅读(177)  评论(0编辑  收藏  举报  来源