美文网首页程序员
Elasticsearch文本分析之Analyzer使用

Elasticsearch文本分析之Analyzer使用

作者: 唯米天空 | 来源:发表于2020-09-08 00:45 被阅读0次

    1. Analyzer概述

    Elasticsearch使用Analyzer来实现文本分析,从而实现将非结构化文本(例如文章正文、邮件内容等)转换为结构化数据,便于检索。Analyzer用于两个场景:对文本字段进行索引和搜索文本。Analyzer只对配置之后的索引生效。

    Analyzer包含3个构建块:

    1. Character filters,字符过滤器,接收原始文本,添加、删除或者改变原始文本的字符。例如HTML标签过滤等。1个Analyzer中可以有0个或者多个字符过滤器。
    2. Tokenizer, 分词器,接收经过字符过滤器后的字符流,对其进行分词。1个Analyzer中只能有1个Tokenizer。
    3. Token filters, 分词过滤器,接收经过分词器后的分词列表,添加、删除或者更改分词。例如大小写转换、同义词添加等。1个Analyzer中可以有0个或者多个分词过滤器。

    Elasticsearch英文官网中对于以上3个构建块的表述很准确,字符过滤器和分词过滤器用的是复数,Character filters和Token filters,而Tokenizer用的是单数,表示只有1个。

    以下通过REST API为例说明Analyzer的使用。

    2. 配置Analyzer

    ES内置了很多Analyzer,譬如standard analyzer,包含1个standard tokenizer、2个token filter:lower case token filter 和 stop token filter,可以不需要任何配置就应用到索引和搜索中。同样,Elasticsearch中也内置了大量Character filters和Token filters。

    Elasticsearch也提供了插件开发接口,用于开发者自己编写Analyzer或者Tokenizer、Character filter和Token filter。譬如各类中文分词插件。

    在实际场景中,通常需要通过组合配置分词插件、内置Analyzer、内置Tokenizer、内置Character filters和内置Token filters等来实现索引需求。

    内置Analyzer(standard analyzer)可以不需要配置而直接应用到索引配置中,本节主要描述自定义的Analyzer。

    自定义Analyzer有2种情况:

    1. 对内置Analyzer或者Analyzer插件的默认配置进行修改。

    2. 在内置Analyzer或者Analyzer插件的基础上,组合添加Tokenizer、Character filters和Token filters。

    不管是哪种情况,都需要创建自定义的Analyzer,不能直接应用原有Analyzer。

    2.1. 修改内置Analyzer的配置

    内置Analyzer包括:

    Fingerprint、Keyword、Language、Pattern、Simple、Standard、Stop、Whitespace。
    

    以修改standard analyzer的属性为例。

    standard analyzer可修改的属性如下:

    官网参考:https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-standard-analyzer.html

    修改standard analyzer的默认属性如下:

    curl -X PUT "localhost:9200/my-index-000001?pretty" -H 'Content-Type: application/json' -d'
    {
      "settings": {
        "analysis": {
          "analyzer": {
            "my_english_analyzer": {
              "type": "standard",
              "max_token_length": 5,
              "stopwords": "_english_"
            }
          }
        }
      }
    }
    '
    

    为方便看request body的格式,扁平化一下,

    settings.analysis.analyzer.<自定义分析器名称>
    {
        "type": "standard",//这里填写要修改的内置分析器名称
        "max_token_length": 5,//这里是内置分析器可以修改的属性
        "stopwords": "_english_"//这里是内置分析器可以修改的属性
    }
    

    可以用下面的方法测试分词效果。

    curl -X POST "localhost:9200/my-index-000001/_analyze?pretty" -H 'Content-Type: application/json' -d'
    {
      "analyzer": "my_english_analyzer",
      "text": "The 2 QUICK Brown-Foxes jumped over the lazy dog\u0027s bone."
    }
    '
    

    2.2. 组合内置模块

    内置模块分为3类:Tokenizer、Filter、Char Filter。

    • Tokenizer: Character group, Classic, Edge n-gram, Keyword, Letter, Lowercase, N-gram, Path hierarchy, Pattern, Simple pattern, Simple pattern split, Standard, Thai, UAX URL, mail, Whitespace
    • Filter: Apostrophe, ASCII folding, CJK bigram, CJK width, Classic, Common grams, Conditional, Decimal digit, Delimited payload, Dictionary decompounder, Edge n-gram, Elision, Fingerprint, Flatten graph, Hunspell, Hyphenation decompounder, Keep types, Keep words, Keyword marker, Keyword repeat, KStem, Length, Limit token count, Lowercase, MinHash, Multiplexer, N-gram, Normalization, Pattern capture, Pattern replace, Phonetic, Porter stem, Predicate script, Remove duplicates, Reverse, Shingle, Snowball, Stemmer, Stemmer override, Stop, Synonym, Synonym graph, Trim, Truncate, Unique, Uppercase, Word delimiter, Word delimiter graph
    • Char Filter: HTML strip, Mapping, Pattern replace

    任意组合内置模块,生成自定义的分析器。例如:

    curl -X PUT "localhost:9200/my-index-000001?pretty" -H 'Content-Type: application/json' -d'
    {
      "settings": {
        "analysis": {
          "analyzer": {
            "my_custom_analyzer": {
              "type": "custom", 
              "tokenizer": "standard",
              "char_filter": [
                "html_strip"
              ],
              "filter": [
                "lowercase",
                "asciifolding"
              ]
            }
          }
        }
      }
    }
    '
    

    为方便看request body的格式,扁平化一下,

    settings.analysis.analyzer.<自定义分析器名称>
    {
        "type": "custom",//这里填写custom,因为要自己组装内置模块形成一个自定义分析器。
        "tokenizer": "standard",,//tokenizer, 字符串,内置tokenizer名称
        "char_filter": ["html_strip"],//char_filter,数组,内置char_filter列表
        "filter": [ "lowercase", "asciifolding" ] //filter,数组,内置filter列表
    }
    

    简言之,格式为从内置模块中,选择1个tokenizer,0个或多个char_filter,0个或多个filter。

    2.3. 所有模块自定义

    与2.2相比,这里对内置模块的属性也进行了修改,将修改属性后的内置模块组合成自定义分析器Analyzer。属于最通用的自定义分析器。

    例如:

    curl -X PUT "localhost:9200/my-index-000001?pretty" -H 'Content-Type: application/json' -d'
    {
      "settings": {
        "analysis": {
          "analyzer": {
            "my_custom_analyzer": { 
              "type": "custom",
              "char_filter": [
                "emoticons"
              ],
              "tokenizer": "punctuation",
              "filter": [
                "lowercase",
                "english_stop"
              ]
            }
          },
          "tokenizer": {
            "punctuation": { 
              "type": "pattern",
              "pattern": "[ .,!?]"
            }
          },
          "char_filter": {
            "emoticons": { 
              "type": "mapping",
              "mappings": [
                ":) => _happy_",
                ":( => _sad_"
              ]
            }
          },
          "filter": {
            "english_stop": { 
              "type": "stop",
              "stopwords": "_english_"
            }
          }
        }
      }
    }
    '
    

    为方便看request body的格式,扁平化一下,

    settings.analysis.analyzer.<自定义分析器名称>
    {
        "type": "custom",//这里填写custom,因为要自己组装自定义模块形成一个自定义分析器。
        "tokenizer": "自定义tokenizer名称",,//tokenizer, 字符串,内置tokenizer或者自定义tokenizer名称
        "char_filter": ["自定义char_filter名称"],//char_filter,数组,内置char_filter和自定义char_filter列表
        "filter": [ "lowercase", "自定义filter名称" ] //filter,数组,内置filter和自定义filter列表
    }
    settings.analysis.tokenizer.<自定义tokenizer名称>
    {
        "type": "pattern", //要修改的tokenizer类型名称
        "pattern": "[ .,!?]" //要修改的属性
    }
    settings.analysis.char_filter.<自定义char_filter名称>
    {
        "type":"mapping", //要修改的char_filter类型名称
        "mappings":[balabala...] //要修改的属性
    }
    settings.analysis.filter.<自定义filter名称>
    {
        "type":"stop", //要修改的filter类型名称
        "stopwords": "_english_" //要修改的属性
    }
    

    简言之,格式为在analysis的子节点中添加各种自定义模块,从中选择1个tokenizer,0个或多个char_filter,0个或多个filter组成自定义分析器Analyzer。

    3. 应用Analyzer

    Analyzer应用在2个场景:

    • 索引(index,在索引中插入数据时进行文本分析)
    • 搜索(search,搜索时对搜索词进行文本分析)

    3.1. 索引场景

    指定index的分析器Analyzer。

    大多数情况下,在创建index时,在mapping参数中为每一个text field都指定一下analyzer是最好的实践。这样的情况下,使用[indexName]/_mapping就能看到每一个text字段的分词器设置。用index templates也可以。

    3.1.1. 为某个字段指定分析器

    创建索引index时,在mapping参数中指定。

    curl -X PUT "localhost:9200/my-index-000001?pretty" -H 'Content-Type: application/json' -d'
    {
      "mappings": {
        "properties": {
          "title": {
            "type": "text",
            "analyzer": "whitespace"
          }
        }
      }
    }
    '
    

    3.1.2. 为index指定默认的分析器

    创建或者更新index的settings时,指定analysis.analyzer.default参数。参数值的类型就是自定义analyzer的类型。

    curl -X PUT "172.22.69.39:9210/ibase-reserved-ansj/_settings?pretty" -H 'Content-Type: application/json' -d'
    {
      "index": {
        "analysis": {
          "analyzer": {
            "cmpv2_ansj": { 
              "type": "custom",
              "tokenizer": "index_ansj",
              "char_filter": [
                "html_strip"
              ]
            },
            "default": { 
              "type": "custom",
              "tokenizer": "index_ansj",
              "char_filter": [
                    "html_strip"
              ]
            }
          }
        }
      }
    }
    '
    

    3.2. 搜索场景

    指定搜索的分析器。

    3.2.1. search检索中,指定分析器。

    curl -X GET "localhost:9200/my-index-000001/_search?pretty" -H 'Content-Type: application/json' -d'
    {
      "query": {
        "match": {
          "message": {
            "query": "Quick foxes",
            "analyzer": "stop"
          }
        }
      }
    }
    '
    

    3.2.2. 在创建index时,mapping参数中,指定text字段的search_analyzer参数。

    curl -X PUT "localhost:9200/my-index-000001?pretty" -H 'Content-Type: application/json' -d'
    {
      "mappings": {
        "properties": {
          "title": {
            "type": "text",
            "analyzer": "whitespace",
            "search_analyzer": "simple"
          }
        }
      }
    }
    '
    

    3.2.3. 在创建index时,在analysis.analyzer参数中,指定default_search字段。即analysis.analyzer.default_search参数。如果设置这个参数,那么analysis.analyzer.default参数也得设置。

    curl -X PUT "localhost:9200/my-index-000001?pretty" -H 'Content-Type: application/json' -d'
    {
      "settings": {
        "analysis": {
          "analyzer": {
            "default": {
              "type": "simple"
            },
            "default_search": {
              "type": "whitespace"
            }
          }
        }
      }
    }
    '
    

    如果上面3种都没有设置,那么会使用field中的analyzer参数值。也就是index时的analyzer。

    4. 测试Analyzer

    可以直接使用/_analyze来测试分词效果。

    curl -X POST "localhost:9200/my-index-000001/_analyze?pretty" -H 'Content-Type: application/json' -d'
    {
      "analyzer": "my_custom_analyzer",
      "text": "I\u0027m a :) person, and you?"
    }
    '
    

    也可以使用/_search来检索

    curl -X GET "localhost:9200/my-index-000001/_search?pretty" -H 'Content-Type: application/json' -d'
    {
      "query": {
        "match": {
          "message": {
            "query": "Quick foxes",
            "analyzer": "stop"
          }
        }
      }
    }
    '

    相关文章

      网友评论

        本文标题:Elasticsearch文本分析之Analyzer使用

        本文链接:https://www.haomeiwen.com/subject/qxnrektx.html