ElasticSearch笔记-分析器

文本分析器(Text analysis)

在ES当中,只有text类型的字段才会用到全文索引。我们在建立索引和搜索时,都会用到分析器。
分析器使ES支持全文索引,搜索的结果是和你搜索的内容相关的,而不是你搜索内容的确切匹配。
分析器之所以能够使搜索支持全文索引,都是因为有分词器(tokenization),它可以将一句话、一篇文章切分成不同的词语,每个词语都是独立的。
分析器除了要做分词,还要做归一化(Normalization)。如匹配大小写不同的词、复数形式的词、同义词。为了解决这些问题,分析器要把这些分词归一化到标准的格式。这样我们在搜索的时候就不用严格的匹配了,相似的词语我们也能够检索出来。

分析器的组成

分析器,无论是内置的,还是自定义的,都是由3部分组成:字符过滤器(character filters)、分词器(tokenizers)、分词过滤器(token filters)。

字符过滤器

字符过滤器接收最原始的文档,并且可以修改和删除其内容,比如:可以把中文的一二三四五六七八九,变成阿拉伯数字123456789。它还可以过滤html标签,并对其进行转义。还可以通过正则表达式,把匹配到的内容转化成其他的内容。一个分析器可以有多个字符过滤器,也可以没有字符过滤器。

分词器

一个分析器只能有一个确定的分词器,它可以把一句话分成若干个词

分词过滤器

分词过滤器接收分词并且可以改变分词,比如:小写分词过滤器,它将接收到的分词全部转换成小写。助词过滤器,它将删除掉一些公共的助词,比如英语里的 the,is,are等,中文里的的,得等。同义词过滤器,它将在你的分词中,添加相应的同义词。一个分析器可以有多个分词过滤器,它们将按顺序执行。

分析器组件调用顺序:字符过滤器 -> 分词器 -> 词项过滤器

测试分析器

ES有分析器的api,我们指定分析器和文本内容,就可以得到分词的结果
测试分析器:

POST _analyze
{
  "analyzer": "standard",
  "text": "The 2 QUICK Brown-Foxes jumped over the lazy dog's bone."
}

测试字符过滤器、分词器、分词过滤器:

POST /_analyze  
{  
  "char_filter": ["html_strip"], 
  "tokenizer": {  
      "type": "standard"  
  },  
  "filter": ["lowercase", "stop"],
  "text": "<html>Elasticsearch is an amazing search engine.</html>"  
} 

配置文本分析器

ES默认给我们配置的分析器是Standard Analyzer。如果标准的分析器不适合你,你可以指定其他的分析器,或者自定义一个分析器。

为指定的字段配置分析器

我们在创建映射时,可以为每一个text类型的字段指定分析器

PUT my_index
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "whitespace"
      }
    }
  }
}

为索引指定默认的分析器

如果我们觉得为每一个字段指定分析器过于麻烦,我们还可以为索引指定一个默认的分析器

PUT my_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "default": {
          "type": "whitespace"
        }
      }
    }
  }
}

自定义分析器

PUT /my_index
{    "settings": {
        "analysis": {
            "char_filter": {         //字符过滤器
                "&_to_and": {            
                    "type":       "mapping",
                    "mappings": [ "&=> and "]    //把&替换为 " and "
                } 
            },
            "tokenizer":   { ...    custom tokenizers     ... },
            "filter":      { 
                "my_stopwords": {    //词单元过滤器 
                    "type":        "stop",
                    "stopwords": [ "the", "a" ]        //移除自定义的停止词
                }                        
            },
            "analyzer":    {         //分析器定义
                "my_analyzer": {
                    "type":           "custom",
                    "char_filter":  [ "html_strip", "&_to_and" ],
                    "tokenizer":      "standard",
                    "filter":       [ "lowercase", "my_stopwords" ]
                }
            }
        }
    }
}

ES内置分析器

Standard Analyzer

默认分词器,根据Unicode联盟定义的单词边界划分文本,支持多语言,小写处理
组成:
(1)Tokenizer:Standard Tokenizer
(2)Token Filters:Lower Case Token Filter

例:POST _analyze
{
  "analyzer": "standard",
  "text": "The 2 QUICK Brown-Foxes jumped over the lazy dog's bone."
}
上面的句子会产生下面的条件:
[ the, 2, quick, brown, foxes, jumped, over, the, lazy, dog's, bone ]

Simple Analyzer

在任何不是字母的地方分隔文本,小写处理
组成:
(1)Tokenizer:Lower Case Tokenizer

POST _analyze
{
  "analyzer": "simple",
  "text": "The 2 QUICK Brown-Foxes jumped over the lazy dog's bone."
}
上面的句子会产生下面的条件:
[ the, quick, brown, foxes, jumped, over, the, lazy, dog, s, bone ]

Whitespace Analyzer

空白字符作为分隔符,不转小写。
组成:
(1)Tokenizer:Whitespace Tokenizer
例:

POST _analyze
{
  "analyzer": "whitespace",
  "text": "The 2 QUICK Brown-Foxes jumped over the lazy dog's bone."
}
上面的句子会产生下面的条件:
[ The, 2, QUICK, Brown-Foxes, jumped, over, the, lazy, dog's, bone. ]

Stop Analyzer

类似于Simple Analyzer,但相比Simple Analyzer,支持删除停止字
停用词指语气助词等修饰性词语,如the, an, 的, 这等
组成 :
(1)Tokenizer:Lower Case Tokenizer
(2)Token Filters:Stop Token Filter
例:

POST _analyze
{
  "analyzer": "stop",
  "text": "The 2 QUICK Brown-Foxes jumped over the lazy dog's bone."
}
上面的句子会产生下面的条件:
[ quick, brown, foxes, jumped, over, lazy, dog, s, bone ]

Keyword Analyzer

不分词,直接将输入作为一个单词输出,它接受给定的任何文本,并输出与单个术语完全相同的文本。
组成:
(1)Tokenizer:Keyword Tokenizer
例:

POST _analyze
{
  "analyzer": "keyword",
  "text": "The 2 QUICK Brown-Foxes jumped over the lazy dog's bone."
}
上面的句子会产生下面的条件:
[ The 2 QUICK Brown-Foxes jumped over the lazy dog's bone. ]

pattern Analyzer

模式分词器使用正则表达式将文本拆分为术语。
通过正则表达式自定义分隔符,默认是\W+,即非字词的符号作为分隔符

Language Analyzer

提供30多种常见语言的分词器

字符过滤器

字符过滤器(character filter)用于在文本分析过程中的早期阶段进行文本预处理。在分词之前,字符过滤器可以对输入的文本进行更改,如去除特定字符、替换字符或处理 HTML/XML 标签。以下是常用的内置字符过滤器:

1. HTML字符过滤器

名称: html_strip
描述: 该字符过滤器用于去除输入文本中的 HTML 和 XML 标签。适用于需要处理包含 HTML 内容的文本,以确保搜索引擎仅处理清晰的文本内容。
用途: 例如,对于来自网页或带有 MARKUP 的数据,使用此过滤器可以删除不必要的标签。

2. 反向字符串过滤器

名称: mapping
描述: 通过映射规则替换输入文本中的字符。用户可以定义自己的映射,指定要替换的字符及其新值。
用途: 可以用于标准化文本,比如将“&”替换为“and”,或者其他字符转换。

3. 逗号和点号过滤器

名称: pattern_replace
描述: 使用正则表达式模式替换文本中的特定字符。这给用户提供了更强大的文本处理能力。
用途: 可以用于复杂的字符替换,如将所有的点(.)替换为空格。

4. 自定义字符过滤器

用户超过上述内置字符过滤器,Elasticsearch 还允许创建自定义字符过滤器。自定义字符过滤器与映射字符过滤器类似,允许用户根据需求指定不同的处理逻辑。
示例:使用字符过滤器
下面是一个简单的示例,展示如何在 Elasticsearch 中配置索引并使用内置字符过滤器:

PUT /my_index  
{  
  "settings": {  
    "analysis": {  
      "char_filter": {  
        "html_strip": {  
          "type": "html_strip"  // 使用 HTML字符过滤器  
        }  
      },  
      "analyzer": {  
        "custom_analyzer": {  
          "type": "custom",  
          "char_filter": ["html_strip"],  // 应用字符过滤器  
          "tokenizer": "standard",  
          "filter": ["lowercase"]  // 继续小写化  
        }  
      }  
    }  
  },  
  "mappings": {  
    "properties": {  
      "content": {  
        "type": "text",  
        "analyzer": "custom_analyzer"  // 使用自定义分析器  
      }  
    }  
  }  
}  

分词器(tokenizers)

Elasticsearch 提供了多种内置分词器,用于处理文本的分析和分词任务。以下是一些常用的内置分词器的详细介绍,包括它们的用途和特点。

1. 标准分词器(Standard Tokenizer)

名称: standard
描述: 基于Unicode文本分词标准,能够适应许多语言,包括英文和其他西方语言。它会分析输入文本并对其进行分词,默认会去除标点符号。
用途: 适用于大多数语言和一般文本的分析,特别适合处理普通的、未经过特殊处理的输入。

2. 空格分词器(Whitespace Tokenizer)

名称: whitespace
描述: 按空格分割文本,不考虑标点符号。这意味着文本将根据空白字符(如空格、制表符)进行分词。
用途: 适合需要将文本按空格划分的场景,通常用于编程语言代码或日志数据等。

3. 字符串分词器(Keyword Tokenizer)

名称: keyword
描述: 将整个输入字符串视为一个单一的词条(token),不进行任何拆分。
用途: 适合需要精确匹配的字段,比如标识符、标签或状态信息。

4. 语言特定分词器(Language-Specific Tokenizers)

Elasticsearch 还提供了一些针对特定语言的分词器,例如:

  • 阿拉伯文分词器(Arabic Tokenizer):
    名称: arabic
    描述: 针对阿拉伯语的文本进行分词,可以进行归一化。
  • 中文分词器(Chinese Tokenizer):
    名称: ik_max_word, ik_smart (IK 分词器)
    描述: 在中文文本处理中被广泛使用,可以进行精细的词语拆分。
  • 法文分词器(French Tokenizer):
    名称: french
    描述: 针对法语的文本进行处理,支持法语特有的词形变化。
  • 德文分词器(German Tokenizer):
    名称: german
    描述: 针对德语文本的分析,有助于处理复合词。

5. N-Gram 分词器(N-Gram Tokenizer)

名称: ngram
描述: 根据配置的大小(如2-gram、3-gram)生成词条。这对于模糊搜索和自动补全非常有用。
用途: 在搜索引擎中,使用 n-gram 可以提高对用户输入的容错能力,常用于自动补全和模糊匹配功能。

6. 句点分词器(Pattern Tokenizer)

名称: pattern
描述: 使用正则表达式从输入文本中分词。用户可以自定义分隔符和模式。
用途: 非常灵活,适合复杂的文本处理需求,能够处理多种不同的输入格式。

7. 自定义分词器(Custom Tokenizer)

除了使用内置的分词器外,Elasticsearch 也允许用户自定义分词器。您可以配置分词器的行为,包括匹配模式、分隔方式等。

分词过滤器(token filters)

Elasticsearch 提供了多种内置的分词过滤器(token filter),用于在分词后对生成的词条进行进一步处理。这些过滤器可以帮助用户去除停用词、词干化(stemming)、小写化、同义词处理等。以下是一些常用的内置分词过滤器:

1. 小写转化过滤器

名称: lowercase
描述: 将所有输入的词条转换为小写字母。这是非常常见的预处理步骤,可以确保在搜索时不区分大小写。
用途: 适用于希望进行大小写不敏感匹配的场景。

2. 停用词过滤器

名称: stop
描述: 去除文本中常见的、几乎对搜索没有帮助的词(如“the”、 “is”、 “at”等)。
用途: 用于提高索引和查询的效率,减少无用的信息。

3. 词干化过滤器

名称: stemmer
描述: 将词条转换为其词干形式。例如,将“running”转换为“run”。
用途: 用于支持模糊的搜索,能够使搜索更具容错能力。

4. 同义词过滤器

名称: synonym
描述: 将给定词条替换为同义词。例如,将“quick”替换为“fast”。同义词的定义可以是单一形式或短语。
用途: 可用于增强用户的查询结果,使其更完整。

5. 英文词干化过滤器

名称: porter_stem
描述: 使用 Porter 词干算法对词条进行词干化处理。
用途: 针对英文文本处理的常用词干化选择。

6. 词语过滤器

名称: length
描述: 根据词条的长度来过滤词条。用户可以指定最大和最小词条长度。
用途: 适用于希望仅保留特定长度的词条的情况。

7. 反向字符串过滤器

名称: reverse
描述: 反转词条的字符顺序。例如,将“abc”转换为“cba”。
用途: 在一些特定的场景下对于查询或索引的需求。

8. 冗余词处理过滤器

名称: word_delimiter
描述: 将复合词拆分成单词或合并相邻的单词。可以调整处理逻辑以适应特定的文本需求。
用途: 适合处理如“user-agent”这样的复合词,使其可以在检索时更有效。
示例:使用分词过滤器
可以将分词过滤器应用于分析器,从而影响索引或搜索的行为。以下是一个使用小写、停用词和词干化过滤器的示例:

PUT /my_index  
{  
  "settings": {  
    "analysis": {  
      "filter": {  
        "my_stop": {  
          "type": "stop",  
          "stopwords": "_english"  // 使用英语停用词  
        },  
        "my_stemmer": {  
          "type": "stemmer",  
          "language": "english"  // 使用英语词干化  
        }  
      },  
      "analyzer": {  
        "my_custom_analyzer": {  
          "type": "custom",  
          "tokenizer": "standard",  
          "filter": [  
            "lowercase",  // 小写化  
            "my_stop",    // 停用词过滤  
            "my_stemmer"  // 词干化  
          ]  
        }  
      }  
    }  
  },  
  "mappings": {  
    "properties": {  
      "content": {  
        "type": "text",  
        "analyzer": "my_custom_analyzer"  // 使用自定义分析器  
      }  
    }  
  }  
}  

参考:
https://www.cnblogs.com/boboooo/p/12836770.html
https://www.cnblogs.com/boboooo/p/12843578.html

posted @ 2021-01-01 16:38  .Neterr  阅读(411)  评论(0)    收藏  举报