ES中分析器(Analyzer)故事版
analyzer
analyzer:指定分析器(character filter、tokenizer、Token filters)。
ES提供的分词器——内置分词器
standard Analyzer—默认分词器,英文按单词切分,并小写处理、过滤符号,中文按单字分词。
simple Analyzer—英文按照单词切分、过滤符号、小写处理,中文按照空格分词。
stop Analyzer—中文英文一切按照空格切分,英文小写处理,停用词过滤(基本不会当搜索条件的无意义的词a、this、is等等),会过滤其中的标点符号。
whitespace Analyzer—中文或英文一切按照空格切分,英文不会转小写。
keyword Analyzer—不进行分词,这一段话整体作为一个词。
java##analyzer delete blog PUT blog { "mappings": { "properties": { "title":{ "type":"text", "analyzer": "standard" } } } } PUT blog/_doc/1 { "title":"定义 默认 对索引 和 查询 都是 有效的" } GET blog/_search { "query": { "term": { "title": "查询" } } }
分析器(Analyzer):数字村的"语言翻译官" 🗣️
想象数字村是一个国际化的村庄,村民说着不同的语言(中文、英文等)。村里有一位语言翻译官,他的工作是把各种语言的内容翻译成村里通用的"搜索语言"。
故事:翻译官的工作流程
当村民提交一段文字时,翻译官会进行三步处理:
1. 字符过滤车间(Character Filter)
- 任务:清理文本杂质
- 操作:
- 去除HTML标签:
<b>Hello</b>
→Hello
- 替换特殊字符:
&
→and
- 处理表情符号:
😊
→[smile]
- 去除HTML标签:
2. 词汇切割车间(Tokenizer)
- 任务:把句子切成单词/词语
- 操作:
- 英文:"Hello World" → ["Hello", "World"]
- 中文:"我爱编程" → ["我", "爱", "编", "程"]
3. 词汇加工车间(Token Filters)
- 任务:精炼词汇
- 操作:
- 转小写:"Hello" → "hello"
- 去除停用词:"a", "the", "is"(这些词太常见,没搜索价值)
- 词干提取:"running" → "run"
村里的翻译团队(内置分析器)
数字村有多个翻译团队,各有特色:
团队名称 | 工作特点 | 比喻 |
---|---|---|
标准团队 (standard) | - 英文:按单词切分 → 转小写 - 中文:按单字切分 - 过滤标点符号 | 严谨的学院派翻译 |
简单团队 (simple) | - 按非字母字符切分(如空格、标点) - 转小写 - 中文会按空格切分 | 粗放型翻译 |
停用词团队 (stop) | - 类似简单团队 - 额外去除停用词(a, the, is等) | 精简型翻译 |
空格团队 (whitespace) | - 严格按空格切分 - 不转小写 - 不过滤标点 | 机械的切分机器 |
关键词团队 (keyword) | - 不切分!整段文本当作一个词 | 只做记录的书记员 |
实战演示:标准团队工作现场
步骤1:聘请标准团队
json
PUT blog
{
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer": "standard" // 指定标准团队
}
}
}
}
步骤2:提交中文内容
json
PUT blog/_doc/1
{
"title": "定义 默认 对索引 和 查询 都是 有效的"
}
步骤3:翻译官的工作成果
标准团队处理流程:
- 字符过滤:无特殊字符,跳过
- 词汇切割:按空格和单字切分 →
["定", "义", " ", "默", "认", " ", "对", "索", "引", " ", "和", " ", "查", "询", " ", "都", "是", " ", "有", "效", "的"]
- 词汇加工:转小写(中文不变)→ 最终词项:
["定", "义", "默", "认", "对", "索", "引", "和", "查", "询", "都", "是", "有", "效", "的"]
步骤4:尝试搜索
json
GET blog/_search
{
"query": {
"term": {
"title": "查询" // 注意:实际存储的是单字"查"和"询"
}
}
}
结果:❌ 找不到文档!
- 原因:标准分析器把中文按单字切分了,所以没有"查询"这个词项
正确使用分析器的技巧
技巧1:中文要用专用分析器
json
PUT blog_cn
{
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer": "ik_smart" // 使用IK中文分词器
}
}
}
}
- IK分析器:会把"定义默认对索引和查询都是有效的"切分为:
["定义", "默认", "对", "索引", "和", "查询", "都是", "有效的"]
技巧2:搜索时指定分析器
json
GET blog/_search
{
"query": {
"match": {
"title": {
"query": "定义索引",
"analyzer": "ik_smart" // 搜索时也用IK分词
}
}
}
}
技巧3:多字段不同分析器
json
PUT products
{
"mappings": {
"properties": {
"name": {
"type": "text",
"analyzer": "ik_max_word", // 存储时细粒度分词
"search_analyzer": "ik_smart", // 搜索时粗粒度分词
"fields": {
"raw": {"type": "keyword"} // 保留原始值
}
}
}
}
}
分析器选择指南
场景 | 推荐分析器 | 原因 |
---|---|---|
英文内容 | standard | 默认够用 |
中文内容 | ik_smart 或 ik_max_word | 中文分词准确 |
代码/标识符 | simple | 按非字母切分 |
标签/分类 | keyword | 整体作为一个标签 |
多语言混合 | icu_analyzer | 支持Unicode和多语言处理 |
记忆口诀
分析器像翻译官,处理文本三步骤:
- 字符过滤 → 洗菜(去杂质)
- 词汇切割 → 切菜(分块)
- 词汇加工 → 炒菜(调味)
团队选择很重要:
- 中文请找 IK 专家(ik_smart/ik_max_word)
- 英文默认 standard
- 标签分类用 keyword
- 停用词多选 stop
记住这个比喻,你就能成为Elasticsearch的"语言大师"!🎯