elasticSearch之API:文本分词,分词器的使用(上)

文章目录

一、简介

本文基于ES7.10版本(阿里云ES稳定版也是7.10版)。

官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/7.10/analysis-overview.html

1、基本概念

文本分析发生在两个时间:

对文档编制索引时,将分析所有文本字段值。

当对文本字段运行全文搜索时,将分析查询字符串(用户正在搜索的文本)。

在大多数情况下,在索引和搜索时应该使用相同的分析器。这确保了字段的值和查询字符串被更改为相同形式的标记。反过来,这确保了令牌在搜索期间按预期匹配。

stopwords(停止词): 是指在文本分析过程中被忽略、过滤掉的高频无意义词汇,其核心作用是优化索引效率、提升检索精度。

2、tokenizer(分词器)和 analyzer(分析器)的区别

(1)区别

Tokenizer(分词器):仅负责 "切割",tokenizer 的唯一职责是把一段连续的文本(字符串)按照特定规则切分成一个个独立的 "词元(token)",它只做 "切割",不做其他处理

Analyzer(分析器):负责 "完整的文本处理流程",analyzer 是一个 "组合组件",它封装了一套完整的文本分析流程,包含 3 个可选阶段(实际至少包含 tokenizer)

字符过滤器(Char Filter):预处理文本(如替换特殊字符、去除 HTML 标签);

分词器(Tokenizer):核心切割步骤(必须有,且只能有一个);

词元过滤器(Token Filter):对切割后的词元做二次处理(如转小写、停用词过滤、同义词替换、词干提取)。

analyzer 的核心就是 tokenizer,所有文本分析最终都要通过 tokenizer 完成切割,analyzer 只是在 tokenizer 的基础上增加了前后处理逻辑。

(2)常见使用场景

1.使用 ES 内置 analyzer(已包含默认 tokenizer)

这是最常用的方式,直接用 ES 预定义的 analyzer(如 standardik_smartwhitespace),无需手动指定 tokenizer,因为 analyzer 已经内置了对应的 tokenizer。

json 复制代码
# 示例:使用内置 standard 分析器(内置 standard tokenizer)
POST _analyze
{
  "analyzer": "standard",
  "text": "Elasticsearch Is Good!"
}
# 输出结果:["elasticsearch", "is", "good"]

2.自定义 analyzer(手动指定 tokenizer + 过滤器)

如果内置 analyzer 不满足需求,你可以自定义 analyzer,必须显式指定一个 tokenizer,还可以搭配 char filter 和 token filter。

json 复制代码
# 示例:自定义分析器,指定 whitespace tokenizer + lowercase 过滤器
PUT my_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_custom_analyzer": {  # 自定义分析器
          "type": "custom",
          "char_filter": ["html_strip"],  # 字符过滤器:去除HTML标签
          "tokenizer": "whitespace",      # 手动指定 tokenizer(空格分词)
          "filter": ["lowercase"]         # 词元过滤器:转小写
        }
      }
    }
  }
}

# 测试自定义分析器
POST my_index/_analyze
{
  "analyzer": "my_custom_analyzer",
  "text": "<p>Elasticsearch Is Good!</p>"
}
# 输出结果:["elasticsearch", "is", "good!"](去除HTML+空格切割+转小写,保留标点)

3.单独测试 tokenizer(仅看切割效果)

虽然 analyzer 必须包含 tokenizer,但你可以单独调用 tokenizer 来测试切割效果(仅用于调试,实际索引/搜索时还是要通过 analyzer):

json 复制代码
POST _analyze
{
  "tokenizer": "whitespace",  # 单独使用 tokenizer
  "text": "Elasticsearch Is Good!"
}
# 输出结果:["Elasticsearch", "Is", "Good!"](仅切割,无转小写)

二、分析器(analyzer)使用

1、配置分析器

(1)测试分析器

从分析 API 的输出中可以看出,分析器不仅将单词转换为术语,还记录顺序或相对位置 (用于短语查询或单词邻近度查询), 原始文本中每个术语的开始和结束字符偏移量 (用于突出显示搜索片段)。

json 复制代码
// 根据空格分词
POST _analyze
{
  "analyzer": "whitespace",
  "text":     "The quick brown fox."
}
json 复制代码
POST _analyze
{
  "tokenizer": "standard",
  	// lowercase:把所有字母转为小写(如 Is → is);
	// asciifolding:把带重音的特殊字符转为普通 ASCII 字符(如 déja 中的 é → e)。
  "filter":  [ "lowercase", "asciifolding" ], 
  "text":      "Is this déja vu?"
}

// 修改指定索引,可以自定义分析器
PUT my-index-000001
{
  "settings": {
    "analysis": {
      "analyzer": {
        "std_folded": { 
          "type": "custom",
          "tokenizer": "standard",
          "filter": [
            "lowercase",
            "asciifolding"
          ]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "my_text": {
        "type": "text",
        "analyzer": "std_folded" 
      }
    }
  }
}
// 查看指定索引的分析器
GET my-index-000001/_analyze 
{
  "analyzer": "std_folded", 
  "text":     "Is this déjà vu?"
}

GET my-index-000001/_analyze 
{
  "field": "my_text", 
  "text":  "Is this déjà vu?"
}

(2)创建自定义分词器

json 复制代码
// 为指定字段指定自定义分词器
PUT my-index-000001
{
  "settings": {
    "analysis": {
      "analyzer": {
        "std_english": { 
          "type":      "standard",
          "stopwords": "_english_"
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "my_text": {
        "type":     "text",
        "analyzer": "standard", 
        "fields": {
          "english": {
            "type":     "text",
            "analyzer": "std_english" // 指定自定义分词器
          }
        }
      }
    }
  }
}

POST my-index-000001/_analyze
{
  "field": "my_text", 
  "text": "The old brown cow"
}

POST my-index-000001/_analyze
{
  "field": "my_text.english", 
  "text": "The old brown cow"
}
json 复制代码
```json
// 配置实例,最多一个字符,并且字母数字按照token处理
PUT my-index-000001
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "tokenizer": "my_tokenizer"
        }
      },
      "tokenizer": {
        "my_tokenizer": {
          "type": "ngram",
          "min_gram": 1,
          "max_gram": 1,
          "token_chars": [
            "letter",
            "digit"
          ]
        }
      }
    }
  }
}

POST my-index-000001/_analyze
{
  "analyzer": "my_analyzer",
  "text": "2 Quick Foxes.你好啊"
}
// 结果:
2 Q u i c k F o x e s 你 好 啊
复制代码
### (3)指定分析器:指定字段
映射索引时,可以使用分析器映射参数为`每个文本字段`指定分析器。
```json
// 为索引中的某个字段,指定分词器
PUT my-index-000001
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "whitespace"
      }
    }
  }
}

(4)指定分析器:索引的默认分析器

还可以使用 analysis.analyzer.default 设置索引默认分析器。

json 复制代码
PUT my-index-000001
{
  "settings": {
    "analysis": {
      "analyzer": {
        "default": {
          "type": "simple"
        }
      }
    }
  }
}

(5)指定查询分析器:指定查询的搜索分析器(一般不需要)

json 复制代码
GET my-index-000001/_search
{
  "query": {
    "match": {
      "message": {
        "query": "Quick foxes",
        "analyzer": "stop" // 指定查询分析器
      }
    }
  }
}

(6)指定查询分析器:指定字段的查询分析器(一般不需要)

json 复制代码
PUT my-index-000001
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "whitespace",
        "search_analyzer": "simple" // 指定查询分析器,一般不需要单独配置
      }
    }
  }
}

(7)指定查询分析器:指定索引默认查询分析器(一般不需要)

json 复制代码
PUT my-index-000001
{
  "settings": {
    "analysis": {
      "analyzer": {
        "default": {
          "type": "simple"
        },
        "default_search": { // 索引默认查询分析器,一般不需要
          "type": "whitespace"
        }
      }
    }
  }
}

2、内置分析器:fingerprint(不常用)

输入文本是小写的,规范化以删除扩展字符,排序,重复数据删除和连接到一个单一的令牌。如果配置了停用词列表,停用词也将被删除。

(1)默认示例

json 复制代码
// 默认示例
POST _analyze
{
  "analyzer": "fingerprint",
  "text": "Yes yes, Gödel said this sentence is consistent and."
}
// 结果:产生一条
{
  "tokens" : [
    {
      "token" : "and consistent godel is said sentence this yes",
      "start_offset" : 0,
      "end_offset" : 52,
      "type" : "fingerprint",
      "position" : 0
    }
  ]
}

(2)可选配置

separator:用于连接术语的字符。默认是空格。

max_output_size:最大字符数,默认255,超过这个数的将被丢弃。

stopwords:停止词,默认停止词_none_

stopwords_path:包含停止字的文件的路径。

json 复制代码
// 配置示例
PUT my-index-000001
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_fingerprint_analyzer": {
          "type": "fingerprint", // 选择分析器
          "stopwords": "_english_", // 停止词
          "separator": "," // 分隔符
        }
      }
    }
  }
}

POST my-index-000001/_analyze
{
  "analyzer": "my_fingerprint_analyzer",
  "text": "Yes yes, Gödel said this sentence is consistent and."
}

// 以下为执行结果:
{
  "tokens" : [
    {
      "token" : "consistent,godel,said,sentence,yes", // 排序、以逗号分隔、去掉英文的停止词
      "start_offset" : 0,
      "end_offset" : 52,
      "type" : "fingerprint",
      "position" : 0
    }
  ]
}

3、内置分析器:keyword(不常用)

(1)默认示例

keyword分析器是一个"noop"分析器,它将整个输入字符串作为单个标记返回。

json 复制代码
// 示例,输入啥就输出啥,输出同样的字符串:The 2 QUICK Brown-Foxes jumped over the lazy dog's bone.
POST _analyze
{
  "analyzer": "keyword",
  "text": "The 2 QUICK Brown-Foxes jumped over the lazy dog's bone."
}

(2)可选配置

keyword分析器不可配置。

4、内置分析器:Language(多语言专用)

支持的语言:arabic, armenian, basque, bengali, brazilian, bulgarian, catalan, cjk, czech, danish, dutch, english, estonian, finnish, french, galician, german, greek, hindi, hungarian, indonesian, irish, italian, latvian, lithuanian, norwegian, persian, portuguese, romanian, russian, sorani, spanish, swedish, turkish, thai.

5、内置分析器:Pattern 正则

Pattern 分析器使用Java正则表达式将文本拆分。正则表达式应该匹配标记分隔符, 而不是标记本身。正则表达式默认为 \W+(所有非单词字符,除了 a-zA-Z0-9_ 之外的所有字符)。

(1)默认示例

json 复制代码
POST _analyze
{
  "analyzer": "pattern",
  "text": "The 2 QUICK Brown-Foxes jumped over the lazy dog's bone."
}

结果如下:

json 复制代码
{
  "tokens" : [
    {
      "token" : "the",
      "start_offset" : 0,
      "end_offset" : 3,
      "type" : "word",
      "position" : 0
    },
    {
      "token" : "2",
      "start_offset" : 4,
      "end_offset" : 5,
      "type" : "word",
      "position" : 1
    },
    {
      "token" : "quick",
      "start_offset" : 6,
      "end_offset" : 11,
      "type" : "word",
      "position" : 2
    },
    {
      "token" : "brown",
      "start_offset" : 12,
      "end_offset" : 17,
      "type" : "word",
      "position" : 3
    },
    {
      "token" : "foxes",
      "start_offset" : 18,
      "end_offset" : 23,
      "type" : "word",
      "position" : 4
    },
    {
      "token" : "jumped",
      "start_offset" : 24,
      "end_offset" : 30,
      "type" : "word",
      "position" : 5
    },
    {
      "token" : "over",
      "start_offset" : 31,
      "end_offset" : 35,
      "type" : "word",
      "position" : 6
    },
    {
      "token" : "the",
      "start_offset" : 36,
      "end_offset" : 39,
      "type" : "word",
      "position" : 7
    },
    {
      "token" : "lazy",
      "start_offset" : 40,
      "end_offset" : 44,
      "type" : "word",
      "position" : 8
    },
    {
      "token" : "dog",
      "start_offset" : 45,
      "end_offset" : 48,
      "type" : "word",
      "position" : 9
    },
    {
      "token" : "s",
      "start_offset" : 49,
      "end_offset" : 50,
      "type" : "word",
      "position" : 10
    },
    {
      "token" : "bone",
      "start_offset" : 51,
      "end_offset" : 55,
      "type" : "word",
      "position" : 11
    }
  ]
}

(2)可选配置

pattern:Java 正则表达式 ,默认值为 \W+(除了 a-zA-Z0-9_ 之外的所有字符)。

flags:Java 正则表达式标志 。标志应采用管道分隔,例如"CASE_INSENSITIVE|COMMENTS"

lowercase:是否转小写,默认true。

stopwords:一个预定义的停止词列表,如 _english_ 或者一个包含停止词列表的数组。默认 _none_

stopwords_path:包含停止字的文件的路径。

json 复制代码
// 示例:除了默认的\W+以外,加上下划线也参与拆分
PUT my-index-000002
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_email_analyzer": {
          "type":      "pattern",
          "pattern":   "\\W|_", 
          "lowercase": true
        }
      }
    }
  }
}

POST my-index-000002/_analyze
{
  "analyzer": "my_email_analyzer",
  "text": "John_Smith@foo-bar.com"
}

// 结果数组为:
[ john, smith, foo, bar, com ]

6、内置分析器:simple

simple 分析器将文本分解为任何非字母字符(如数字、空格、连字符和撇号)处的标记,丢弃非字母字符,并转为小写。

(1)默认示例

json 复制代码
// 默认示例:
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 ]

7、内置解析器:standard(默认)

standard分析器是默认分析器。 它基于语法的标记化(基于 Unicode 文本 分割算法),并适用于大多数语言。

(1)默认示例

json 复制代码
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 ]

(2)可选配置

max_token_length:最大长度,默认255。

stopwords:一个预定义的停止词列表,如 _english_ 或者一个包含停止词列表的数组。默认 _none_

stopwords_path:包含停止字的文件的路径。

json 复制代码
// 示例:最长5个字符
PUT my-index-000001
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_english_analyzer": {
          "type": "standard",
          "max_token_length": 5,
          "stopwords": "_english_"
        }
      }
    }
  }
}

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

// 结果数组:
[ 2, quick, brown, foxes, jumpe, d, over, lazy, dog's, bone ]

8、内置解析器:stop

stop分析器与simple 分析器相同 但增加了对删除停止词的支持。 它默认使用_english_停止词。

(1)默认示例

json 复制代码
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 ]

(2)可选配置

stopwords:一个预定义的停止词列表,如 _english_ 或者一个包含停止词列表的数组。默认 _english_

stopwords_path:包含停止字的文件的路径。

json 复制代码
// 示例:指定停止词
PUT my-index-000001
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_stop_analyzer": {
          "type": "stop",
          "stopwords": ["the", "over"]
        }
      }
    }
  }
}

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

9、内置解析器:whitespace

whitespace 通过空格进行词语拆分。

不可以额外配置。

(1)默认示例

json 复制代码
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. ]

三、分词器(tokenizer)使用

分词器接收一段字符流,将其拆分成一个个单独的"标记"(通常是指单个单词),然后输出一个由这些标记组成的新字符流。

1、内置分词器:char_group

char_group分词器会在遇到属于特定字符集的字符时,将文本拆分。

这种分词方式特别适用于那些需要简单自定义分词规则的情况,同时也不适合那些无法承受使用pattern分词器所带来的性能开销的场景。

可选配置:
tokenize_on_chars:这是一个包含用于对字符串进行分词处理的字符列表。每当遇到该列表中的某个字符时,就会开始一个新的分词单元。这些字符既可以是单个字符(例如 -),也可以是字符组合:空白、字母、数字、标点、符号。
max_token_length:token的最大长度。如果遇到超过此长度的token,那么它将会以 max_token_length 为间隔被分割开来。默认值为 255

json 复制代码
// 示例,通过空格、 - 、换行来分词
POST _analyze
{
  "tokenizer": {
    "type": "char_group",
    "tokenize_on_chars": [
      "whitespace",
      "-",
      "\n"
    ]
  },
  "text": "The QUICK brown-fox"
}
// 输出结果数组
The  QUICK  brown  fox

2、内置分词器:classic

classic 分词器是一种基于语法的分词工具,非常适合用于处理英语文档,除了英语,对其他语言不是很友好。

该分词器具备一些规则,可用于特别处理缩写词、公司名称、电子邮件地址以及互联网主机名等内容。

它会在遇到任何标点符号时对单词进行分割,并同时删除这些标点符号。不过,如果某个点后面没有跟随任何空白字符,那么这个点仍然会被视为该单词的一部分。

它会根据连字符来分割单词;但如果某个词中包含数字,那么整个词就会被视为产品编号而不会被分割。

它将电子邮件地址和互联网主机名视为一个统一的标识符。

可选配置:
max_token_length:token的最大长度。如果遇到超过此长度的token,那么它将会以 max_token_length 为间隔被分割开来。默认值为 255

json 复制代码
// 示例:
POST _analyze
{
  "tokenizer": "classic",
  "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 ]
json 复制代码
// 示例:指定分词器,最大token为5
PUT my-index-000001
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "tokenizer": "my_tokenizer"
        }
      },
      "tokenizer": {
        "my_tokenizer": {
          "type": "classic",
          "max_token_length": 5
        }
      }
    }
  }
}

POST my-index-000001/_analyze
{
  "analyzer": "my_analyzer",
  "text": "The 2 QUICK Brown-Foxes jumped over the lazy dog's bone."
}
// 结果数组:
[ The, 2, QUICK, Brown, Foxes, jumpe, d, over, the, lazy, dog's, bone ]

3、内置分词器:edge_ngram

edge_ngram分词器在遇到列表中指定的某个字符时,会首先将文本分解成单词;随后,它会为每个单词生成N-gram结构,其中N-gram的起始位置始终固定在该单词的开头。

在默认设置下,edge_ngram分词器会将输入的文本视为一个整体单元,并生成长度至少为1、最多为2的N-gram序列。

这些默认的字符长度设置几乎毫无用处。在使用之前,你必须先对相关参数进行配置。
通常,我们建议在索引创建时和搜索时都使用相同的analyzer分词器。但对于edge_ngram分词器来说,建议则有所不同。只有在索引创建时使用edge_ngram分词器才是合理的,这样才能确保索引中包含那些不完整的单词,从而便于进行匹配操作。而在搜索时,则只需搜索用户输入的完整词汇即可(前缀匹配)。

json 复制代码
// 示例
POST _analyze
{
  "tokenizer": "edge_ngram",
  "text": "Quick Fox"
}
// 结果数组
[ Q, Qu ]

可选配置:
min_gram:一个"gram"中字符的最小长度。默认值为1
max_gram:一个 Gram 中字符的最大长度。默认值为 2。(规定最大为10,因此长度超过10个字符的搜索词可能无法被搜索出来)
token_chars:应该被包含在标记中的字符类别。Elasticsearch会将对那些不属于所指定类别的字符进行分割处理。默认值为[](保留所有字符)。
custom_token_chars:应被视为令牌组成部分的自定义字符。(可选:letter - 字母、digit - 数字、whitespace - 空格、punctuation - 标点、symbol - 符号、custom - 自定义)

json 复制代码
// 示例:将字母和数字都视为分词单元,并生成长度至少为2、最多为10的分词结果。
PUT my-index-00001
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "tokenizer": "my_tokenizer"
        }
      },
      "tokenizer": {
        "my_tokenizer": {
          "type": "edge_ngram",
          "min_gram": 2,
          "max_gram": 10,
          "token_chars": [
            "letter",
            "digit"
          ]
        }
      }
    }
  }
}

POST my-index-00001/_analyze
{
  "analyzer": "my_analyzer",
  "text": "2 Quick Foxes."
}
// 结果数组:(相当于会前缀匹配)
[ Qu, Qui, Quic, Quick, Fo, Fox, Foxe, Foxes ]
json 复制代码
// 使用示例:
PUT my-index-00001
{
  "settings": {
    "analysis": {
      "analyzer": {
        "autocomplete": {
          "tokenizer": "autocomplete",
          "filter": [
            "lowercase" // 小写
          ]
        },
        "autocomplete_search": {
          "tokenizer": "lowercase" // 搜索分析器只需要转小写即可,不需要再经过tokenizer
        }
      },
      "tokenizer": {
        "autocomplete": {
          "type": "edge_ngram",
          "min_gram": 2,
          "max_gram": 10,
          "token_chars": [
            "letter"
          ]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "autocomplete",
        "search_analyzer": "autocomplete_search"
      }
    }
  }
}

PUT my-index-00001/_doc/1
{
  "title": "Quick Foxes"  // 分词为:[qu, qui, quic, quick, fo, fox, foxe, foxes]
}

POST my-index-00001/_refresh

GET my-index-00001/_search
{
  "query": {
    "match": {
      "title": {
        "query": "Quick Fo",  // 搜索[quick, fo],不需要再进行edge_ngram分词
        "operator": "and"
      }
    }
  }
}

4、内置分词器:keyword

keyword 分词器接收任何输入的文本,然后将其原封不动地作为单个词项输出出来。

json 复制代码
// 示例
POST _analyze
{
  "tokenizer": "keyword",
  "text": "New York"
}
// 结果数组:
[ New York ]

可选配置:
buffer_size:在一次操作中读取到术语缓冲区中的字符数量。默认值为 256。术语缓冲区的容量会按照这个数值逐渐增加,直到所有文本都被读取完毕为止。建议不要更改这个设置。

json 复制代码
// 通常与过滤器一起使用:
POST _analyze
{
  "tokenizer": "keyword",
  "filter": [ "lowercase" ],
  "text": "john.SMITH@example.COM"
}

// 结果:转小写
[ john.smith@example.com ]

5、内置分词器:letter

letter 遇到非字母字符,就会将文本分解成各个词素。但是对于汉语,通常支持不好,因为汉语不是用空格分隔的。

json 复制代码
// 示例
POST _analyze
{
  "tokenizer": "letter",
  "text": "The 2 QUICK Brown-Foxes jumped over the lazy dog's bone."
}
// 结果:
[ The, QUICK, Brown, Foxes, jumped, over, the, lazy, dog, s, bone ]

6、内置分词器:lowercase

lowercase分词器每当遇到非字母字符时,它就会将文本分解成各个词素,同时还会将所有词素转换为小写形式。

从功能上来说,它相当于letter分词器与letter词元过滤器的结合体;不过它的效率更高,因为能够一次性完成这两项操作。

json 复制代码
// 示例
POST _analyze
{
  "tokenizer": "lowercase",
  "text": "The 2 QUICK Brown-Foxes jumped over the lazy dog's bone."
}
// 结果数组:转小写并且将单词分隔
[ the, quick, brown, foxes, jumped, over, the, lazy, dog, s, bone ]

7、内置分词器:ngram (可用,将词语拆成单个字)

ngram 首先将文本分解为单词,只要它遇到指定字符列表中的一个,然后它发出 指定长度的每个单词的 N 元语法 。

就像一个滑动窗口,可以在单词上移动-指定长度的连续字符序列。它们对于查询不使用空格或具有长复合词的语言(如德语)非常有用。

默认,ngram 标记器将初始文本视为单个标记,并生成最小长度为 1、最大长度为 2 的 N-gram。

json 复制代码
// 示例
POST _analyze
{
  "tokenizer": "ngram",
  "text": "Quick Fox"
}

// 结果数组:
[ Q, Qu, u, ui, i, ic, c, ck, k, "k ", " ", " F", F, Fo, o, ox, x ]

可选配置:
min_gram:一个字符的最小长度,默认1
max_gram:一个字符的最大长度,默认2
token_chars:应包含在标记中的字符类。Elasticsearch 将对不属于指定类的字符进行拆分。默认 [](保留所有字符)。(可选:letter - 字母、digit - 数字、whitespace - 空格、punctuation - 标点、symbol - 符号、custom - 自定义)
custom_token_chars:应视为标记一部分的自定义字符。

json 复制代码
// 配置实例,最多一个字符,并且字母数字按照token处理
PUT my-index-000001
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "tokenizer": "my_tokenizer"
        }
      },
      "tokenizer": {
        "my_tokenizer": {
          "type": "ngram",
          "min_gram": 1,
          "max_gram": 1,
          "token_chars": [
            "letter",
            "digit"
          ]
        }
      }
    }
  }
}

POST my-index-000001/_analyze
{
  "analyzer": "my_analyzer",
  "text": "2 Quick Foxes.你好啊"
}
// 结果:
2 Q u i c k F o x e s 你 好 啊

8、内置分词器:path_hierarchy (用于文件路径)

path_hierarchy 分词器会处理像文件系统路径这样的层次结构数据,根据路径分隔符对路径进行分割,并为路径中的每个组成部分生成一个对应的token。

json 复制代码
// 示例:
POST _analyze
{
  "tokenizer": "path_hierarchy",
  "text": "/one/two/three"
}
// 结果数组
[ /one, /one/two, /one/two/three ]

可选配置:
delimiter:用于作为路径分隔符的字符。默认值为 /
replacement:一个可选的替换字符,用于作为分隔符。默认值为 delimiter
buffer_size:指在一次操作中读取到术语缓冲区中的字符数量。默认值为 1024。术语缓冲区的容量会按照这个数值逐渐增加,直到所有文本都被读取完毕为止。建议不要更改这一设置。
reverse:如果设置为 true,则会以相反的顺序输出这些令牌。默认值为 false
skip:需要跳过的初始令牌数量。默认值为 0

json 复制代码
// 示例:按照-字符来进行分割,并将这些字符替换为/。前两个被分成的"词元"会被忽略掉。
PUT my-index-000001
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "tokenizer": "my_tokenizer"
        }
      },
      "tokenizer": {
        "my_tokenizer": {
          "type": "path_hierarchy",
          "delimiter": "-",
          "replacement": "/",
          "skip": 2
        }
      }
    }
  }
}

POST my-index-000001/_analyze
{
  "analyzer": "my_analyzer",
  "text": "one-two-three-four-five"
}
// 结果数组:
[ /three, /three/four, /three/four/five ]
// 如果我们将 reverse 设置为 true,那么就会产生如下结果:
[ one/two/three/, two/three/, three/ ]

9、内置分词器:pattern

pattern 分词工具会使用正则表达式:一旦遇到单词分隔符,就会将文本分割成各个词元;或者,它会将符合正则表达式的整个文本片段直接作为词元来处理。

默认的模式是\W+,除了 a-zA-Z0-9_ 之外的所有字符。

json 复制代码
// 示例
POST _analyze
{
  "tokenizer": "pattern",
  "text": "The foo_bar_size's default is 5."
}
// 结果:
[ The, foo_bar_size, s, default, is, 5 ]

可选配置:
pattern:Java正则表达式,默认使用的是模式\W+
flags:Java 正则表达式标志 。标志应采用管道分隔,例如"CASE_INSENSITIVE|COMMENTS"
group:应该提取哪个捕获组作为标记。默认值为 -1(即按该捕获组进行分割)。

json 复制代码
// 示例:按照逗号进行分隔
PUT my-index-000001
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "tokenizer": "my_tokenizer"
        }
      },
      "tokenizer": {
        "my_tokenizer": {
          "type": "pattern",
          "pattern": ","
        }
      }
    }
  }
}

POST my-index-000001/_analyze
{
  "analyzer": "my_analyzer",
  "text": "comma,separated,values"
}
// 结果数组:
[ comma, separated, values ]

10、内置分词器:simple_pattern

simple_pattern 使用正则表达式来捕获符合条件的文本,并将其作为术语进行处理。虽然它所支持的正则表达式功能比pattern分词器要有限,但分词速度通常更快。

这个分词器使用了Lucene正则表达式

可选配置:
pattern:Lucene正则表达式,默认值为空字符串。

json 复制代码
// 示例:生成的token都为三位数
PUT my-index-000001
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "tokenizer": "my_tokenizer"
        }
      },
      "tokenizer": {
        "my_tokenizer": {
          "type": "simple_pattern",
          "pattern": "[0123456789]{3}"
        }
      }
    }
  }
}

POST my-index-000001/_analyze
{
  "analyzer": "my_analyzer",
  "text": "fd-786-335-514-x"
}
// 结果:
[ 786, 335, 514 ]

11、内置分词器:simple_pattern_split

simple_pattern_split 分词器会使用正则表达式,在匹配到相应模式时将输入内容分割成各个词元。虽然它所支持的正则表达式功能比pattern分词器要有限,但分词速度通常更快。

分词器使用了Lucene正则表达式,默认的模式是空字符串,这种模式会生成一个包含全部输入内容的术语。因此,这个分词器应该始终使用非默认的模式进行配置。

可选配置:
pattern:一个 Lucene 正则表达式,默认值为空字符串。

json 复制代码
// 基于下划线分隔
PUT my-index-000001
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "tokenizer": "my_tokenizer"
        }
      },
      "tokenizer": {
        "my_tokenizer": {
          "type": "simple_pattern_split",
          "pattern": "_"
        }
      }
    }
  }
}

POST my-index-000001/_analyze
{
  "analyzer": "my_analyzer",
  "text": "an_underscored_phrase"
}
// 结果数组:
[ an, underscored, phrase ]

12、内置分词器:standard (默认)

standard 分词工具提供了基于语法的分词功能(其分词原理遵循Unicode标准附录#29中规定的Unicode文本分割算法),并且适用于大多数语言。

json 复制代码
POST _analyze
{
  "tokenizer": "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 ]

可选配置:
max_token_length:令牌的最大长度。如果遇到超过此长度的令牌,那么它将会以 max_token_length 为间隔被分割开来。默认值为 255。

json 复制代码
// 示例:将standard分词器的分词数量设置为5
PUT my-index-000001
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "tokenizer": "my_tokenizer"
        }
      },
      "tokenizer": {
        "my_tokenizer": {
          "type": "standard",
          "max_token_length": 5
        }
      }
    }
  }
}

POST my-index-000001/_analyze
{
  "analyzer": "my_analyzer",
  "text": "The 2 QUICK Brown-Foxes jumped over the lazy dog's bone."
}
// 结果数组:
[ The, 2, QUICK, Brown, Foxes, jumpe, d, over, the, lazy, dog's, bone ]

13、内置分词器:thai (泰语)

thai分词器会使用Java自带的泰语分词算法来将泰语文本分割成单词。对于其他语言的文本,通常也会采用与standard分词器相同的方式进行处理。

json 复制代码
POST _analyze
{
  "tokenizer": "thai",
  "text": "การที่ได้ต้องแสดงว่างานดี"
}
// 结果:
[ การ, ที่, ได้, ต้อง, แสดง, ว่า, งาน, ดี ]

14、内置分词器:uax_url_email

uax_url_email 分词器与standard分词器类似,不同之处在于它能够将URL和电子邮件地址识别为独立的标记。

json 复制代码
// 示例:
POST _analyze
{
  "tokenizer": "uax_url_email",
  "text": "Email me at john.smith@global-international.com"
}
// 结果:
[ Email, me, at, john.smith@global-international.com ]
// 而standard的分词器会产生如下结果:
[ Email, me, at, john.smith, global, international.com ]

可选配置:
max_token_length:令牌的最大长度。如果遇到超过此长度的令牌,那么它将会以 max_token_length 为间隔被分割开来。默认值为 255。

json 复制代码
// 示例:将uax_url_email分词器的分词数量设置为5(仅用于演示目的)。
PUT my-index-000001
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "tokenizer": "my_tokenizer"
        }
      },
      "tokenizer": {
        "my_tokenizer": {
          "type": "uax_url_email",
          "max_token_length": 5
        }
      }
    }
  }
}

POST my-index-000001/_analyze
{
  "analyzer": "my_analyzer",
  "text": "john.smith@global-international.com"
}
// 结果数组:
[ john, smith, globa, l, inter, natio, nal.c, om ]

15、内置分词器:whitespace

whitespace 分词器一遇到空白字符,就会将文本分解成各个词素。

json 复制代码
POST _analyze
{
  "tokenizer": "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. ]

可选配置:
max_token_length:令牌的最大长度。如果遇到超过此长度的令牌,那么它将会以 max_token_length 为间隔被分割开来。默认值为 255。

四、IK中文分词器

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

1、什么是IK分词器

分词:即把一段中文或者别的划分成一个个的关键字,我们在搜索时候会把自己的信息进行分词,会把数据库中或者索引库中的数据进行分词,然后进行---个匹配操作,默认的中文分词是将毎个字看成一个词,比如"我爱狂神"会被分为"我""爱""狂"神",这显然是不符合要求的,所以我们需要安装中文分词器IK来解决这个问题。

如果要使用中文,建议使用IK分词器!

IK提供了两个分词算法: ik_smart和 ik_max_word,其中 ik_smart为最少切分,ik_max_word为最细粒度划分!

2、离线安装(下载与es对应的版本!!!否则会启动报错)

①下载完,解压到ES目录下

D:\es\elasticsearch-7.6.0\plugins\elasticsearch-analysis-ik-7.6.0

②重启es,会出现加载ik插件

bash 复制代码
[2021-05-07T09:51:29,253][INFO ][o.e.p.PluginsService     ] [DESKTOP-KAO1R1F] loaded plugin [analysis-ik]

③使用elasticsearch-plugin.bat,查看插件

3、使用kibana测试

json 复制代码
GET _analyze
{
  "analyzer" : "ik_smart",
  "text" : "中国共产党"
}

{
  "tokens" : [
    {
      "token" : "中国共产党",
      "start_offset" : 0,
      "end_offset" : 5,
      "type" : "CN_WORD",
      "position" : 0
    }
  ]
}
json 复制代码
GET _analyze
{
  "analyzer" : "ik_max_word",
  "text" : "中国共产党"
}

{
  "tokens" : [
    {
      "token" : "中国共产党",
      "start_offset" : 0,
      "end_offset" : 5,
      "type" : "CN_WORD",
      "position" : 0
    },
    {
      "token" : "中国",
      "start_offset" : 0,
      "end_offset" : 2,
      "type" : "CN_WORD",
      "position" : 1
    },
    {
      "token" : "国共",
      "start_offset" : 1,
      "end_offset" : 3,
      "type" : "CN_WORD",
      "position" : 2
    },
    {
      "token" : "共产党",
      "start_offset" : 2,
      "end_offset" : 5,
      "type" : "CN_WORD",
      "position" : 3
    },
    {
      "token" : "共产",
      "start_offset" : 2,
      "end_offset" : 4,
      "type" : "CN_WORD",
      "position" : 4
    },
    {
      "token" : "党",
      "start_offset" : 4,
      "end_offset" : 5,
      "type" : "CN_CHAR",
      "position" : 5
    }
  ]
}

②有些词被拆分了,需要自己来配置分词

重启es看细节

bash 复制代码
[2021-05-07T10:21:48,875][INFO ][o.e.g.GatewayService     ] [DESKTOP-KAO1R1F] recovered [5] indices into cluster_state
[2021-05-07T10:21:49,223][INFO ][o.w.a.d.Monitor          ] [DESKTOP-KAO1R1F] try load config from D:\es\elasticsearch-7.6.0\config\analysis-ik\IKAnalyzer.cfg.xml
[2021-05-07T10:21:49,228][INFO ][o.w.a.d.Monitor          ] [DESKTOP-KAO1R1F] try load config from D:\es\elasticsearch-7.6.0\plugins\elasticsearch-analysis-ik-7.6.0\config\IKAnalyzer.cfg.xml
[2021-05-07T10:21:49,751][INFO ][o.w.a.d.Monitor          ] [DESKTOP-KAO1R1F] [Dict Loading] D:\es\elasticsearch-7.6.0\plugins\elasticsearch-analysis-ik-7.6.0\config\cxf.dic

4、在线安装

bash 复制代码
# 拓展:可以在线安装
#查看已安装插件
bin/elasticsearch-plugin list
#安装插件
bin/elasticsearch-plugin install analysis-icu
#删除插件
bin/elasticsearch-plugin remove analysis-icu
json 复制代码
# 测试分词效果
POST _analyze
{
    "analyzer":"icu_analyzer",
    "text":"中华人民共和国"
}
#ES的默认分词设置是standard,会单字拆分
POST _analyze
{
    "analyzer":"standard",
    "text":"青岛青岛青岛"
}

#ik_smart:会做最粗粒度的拆
POST _analyze
{
    "analyzer": "ik_smart",
    "text": "青岛青岛青岛"
 }

#ik_max_word:会将文本做最细粒度的拆分
POST _analyze
{
    "analyzer":"ik_max_word",
    "text":"青岛青岛青岛"
}
json 复制代码
# 创建索引时可以指定IK分词器作为默认分词器
PUT /es_db
{
    "settings" : {
        "index" : {
            "analysis.analyzer.default.type": "ik_max_word"
        }
    }
}

5、拓展:查询指定索引分词器

json 复制代码
GET /search_index/_analyze
{
  "analyzer" : "search_index_analyzer",
  "text" : "xxxxxxxxxxxxxxxx"
}

相关推荐
☀Mark_LY2 小时前
elasticsearch7集群Linux部署
linux·elasticsearch
徐先生 @_@|||2 小时前
大数据技术栈演进:从MapReduce到云原生计算的全面对比(2026年)
大数据·hadoop·云原生·spark·mapreduce
TechubNews2 小时前
巨鲸入海:纽交所代币化证券平台瞄准全天候交易与即时结算
大数据·人工智能
徐先生 @_@|||2 小时前
大数据处理框架(Hadoop VS PySpark)
大数据·hadoop·分布式·spark·k8s·yarn
yumgpkpm6 小时前
银行智能数据平台在Cloudera CDH6\CDP 7\CMP 7平台下的具体使用配置流程
大数据·hive·hadoop·数据挖掘·flink·spark·cloudera
秦拿希12 小时前
【paimon-trino】trino整合paimon元数据访问s3
大数据·trino·paimon
kuankeTech13 小时前
解决内外贸双轨制难题,外贸ERP智能引擎同步管理国内外合规与标准
大数据·人工智能·数据可视化·软件开发·erp
q_354888515314 小时前
AI大模型:python新能源汽车推荐系统 协同过滤推荐算法 Echarts可视化 Django框架 大数据毕业设计(源码+文档)✅
大数据·人工智能·python·机器学习·信息可视化·汽车·推荐算法