es 分析器
分析器一般用在下面两个场景中:
- ·创建或更新文档时(合称索引时),对相应的文本字段进行分词处理;
- ·查询文本字段时,对查询语句进行分词。
ES中的分析器有很多种,但是所有分析器的结构都遵循三段式原则,即字符过滤器、分词器和词语过滤器。
其中,字符过滤器可以有0个或多个,分词器必须只有一个,词语过滤器可以有0个或多个。从整体上来讲,三个部分的数据流方向为字符过滤器→分词器→分词过滤器。如图所示为一个分析器的构成示例。
图 分析器构成示例
对于不同的分析器,上述三部分的工作内容是不同的,为了正确匹配,如果在数据写入时指定了某个分析器,那么在匹配查询时也需要设定相同的分析器对查询语句进行分析。
字符过滤器
字符过滤器是分析器处理文本数据的第一道工序,它接收原始的字符流,对原始字符流中的字符进行添加、删除或者转换操作,进而改变原始的字符流。
表 ES内置的字符过滤器
分词器
分词器在分析器中负责非常重要的一环工作——按照规则来切分词语
分词器对文本进行切分后,需要保留词语与原始文本之间的对应关系,因此分词器还负责记录每个Token的位置,以及开始和结束的字符偏移量。
表 ES内置的分词器
分词过滤器
分词过滤器接收分词器的处理结果,并可以将切分好的词语进行加工和修改,进而对分词结果进行规范化、统一化和优化处理。
表 ES内置的分词过滤器
分析器的使用
ES提供了分析器的调用API,使用户可以方便地对比不同分析器的分析结果。另外,ES提供了一些开箱即用的内置分析器,这些分析器其实就是字符过滤器、分词器和分词过滤器的组合体,可以在索引建立时和搜索时指定使用这些分析器。当然,如果这些分析器不符合需求,用户还可以自定义分析器。
测试分析API
为了更好地理解分析器的运行结果,可以使用ES提供的分析API进行测试。在DSL中可以直接使用参数analyzer来指定分析器的名称进行测试,分析API的请求形式如下:
POST /_analyze { "analyzer": ${analyzer_name}, //指定分析器名称 "text":${analyzer_text} //待分析文本 }
以下示例使用standard分析器分析一段英文:
POST /_analyze { "analyzer": "standard", //指定分析器名称为standard "text": "The letter tokenizer is not configurable." //待分析文本 }
上述文本的分析结果如下:
{ "tokens" : [ //分析器将文本切分后的分析结果 { "token" : "the", //将文本切分后的第一个词语 "start_offset" : 0, //该词在文本中的起始偏移位置 "end_offset" : 3, //该词在文本中的结束偏移位置 "type" : "<ALPHANUM>", //词性 "position" : 0 //该词语在原文本中是第0个出现的词语 }, { "token" : "letter", "start_offset" : 4, "end_offset" : 10, "type" : "<ALPHANUM>", "position" : 1 }, { "token" : "tokenizer", "start_offset" : 11, "end_offset" : 20, "type" : "<ALPHANUM>", "position" : 2 }, … ] }
根据以上结果可以看到,standard分析器对文本进行分析时,按照空格把上面的句子进行了分词。分析API返回信息的参数说明如下:
- ·token:文本被切分为词语后的某个词语;
- ·start_offset:该词在文本中的起始偏移位置;
- ·end_offset:该词在文本中的结束偏移位置;
- ·type:词性,各个分词器的值不一样;
- ·position:分词位置,指明该词语在原文本中是第几个出现的。
start_offset和end_offset组合起来就是该词在原文本中占据的起始位置和结束位置。
除了指定分析器进行请求分析外,还可以指定某个索引的字段,使用这个字段对应的分析器对目标文本进行分析。
POST /hotel/_analyze { //使用酒店索引的title字段对应的分析器分析文本 "field": "title", "text": "金都嘉怡假日酒店" }
还可以在API中自定义分析器对文本进行分析
POST /_analyze { "tokenizer": "standard", //使用standard分词器 "filter":["lowercase"], //使用Lower Case分词过滤器 "text": "JinDu JiaYi Holiday Hotel" //待分析文本 }
内置分析器
ES已经内置了一些分析器供用户使用,在默认情况下,一个索引的字段类型为text时,该字段在索引建立时和查询时的分析器是standard。standard分析器是由standard分词器、Lower Case分词过滤器和Stop Token分词过滤器构成的。注意,standard分析器没有字符过滤器。
除了standard分析器之外,ES还提供了simple分析器、language分析器、whitespace分析器及pattern分析器等,这些分析器的功能如表所示。
表 ES内置的分析器
索引时使用分析器
文本字段在索引时需要使用分析器进行分析,ES默认使用的是standard分析器。如果需要指定分析器,一种方式是在索引的settings参数中设置当前索引的所有文本字段的分析器,另一种方式是在索引的mappings参数中设置当前字段的分析器。
以下示例在settings参数中指定在酒店索引的所有文本字段中使用simple分析器进行索引构建。
PUT /hotel { "settings": { "analysis": { "analyzer": { //指定所有text字段索引时使用simple分析器 "default": { "type": "simple" } } } }, "mappings": { "properties": { … } } }
以下示例在mappings参数中指定在酒店索引的title字段中使用whitespace分析器进行索引构建。
PUT /hotel { "mappings": { "properties": { "title": { "type": "text", //指定索引中的title字段索引时使用whitespace分析器 "analyzer": "whitespace" }, … } } }
搜索时使用分析器
为了搜索时更加协调,在默认情况下,ES对文本进行搜索时使用的分析器和索引时使用的分析器保持一致。当然,用户也可以在mappings参数中指定字段在搜索时使用的分析器。如下示例展示了这种用法:
PUT /hotel { "mappings": { "properties": { "title": { "type": "text", "analyzer": "whitespace", //索引时使用whitespace分析器 "search_analyzer": "whitespace" //搜索时使用whitespace分析器 }, … } } }
注意,这里指定的搜索分析器和索引时的分析器是一致的,但是在大多数情况下是没有必要指定的,因为在默认情况下二者就是一致的。如果指定的搜索分析器和索引时的分析器不一致,则ES在搜索时可能出现有不符合预期的匹配情况,因此该设置在使用时需要慎重选择。
自定义分析器
当系统内置的分析器不满足需求时,用户可以使用自定义分析器。
首先,需要在索引创建的DSL中定义分析器comma_analyzer,该分析器中只有一个分词组件,该分词组件使用逗号进行词语切分;然后在mappings中使用analyzer参数指定字段sup_env的分析器为定义好的comma_analyzer分析器。具体的DSL如下:
PUT /hotel { "settings": { "analysis": { "analyzer": { "comma_analyzer": { //自定义分析器 "tokenizer": "comma_tokenizer" //使用comma_tokenizer分词器 } }, "tokenizer": { //定义分词器 "comma_tokenizer": { "type": "pattern", "pattern": "," //指定切分时使用的分隔符 } } } }, "mappings": { "properties": { "title": { "type": "text", "analyzer": "whitespace", //设定title字段索引时使用whitespace分析器 //设定title字段搜索时使用whitespace分析器 "search_analyzer": "whitespace" }, "sup_env": { "type": "text", //设置sup_env字段使用comma_analyzer分析器 "analyzer": "comma_analyzer" }, … } } }
下面向酒店索引中插入几条数据:
POST /_bulk {"index":{"_index":"hotel","_id":"001"}} {"title": "金都嘉怡假日酒店","city": "北京","price": 337.00,"sup_env":"APP,H5"} {"index":{"_index":"hotel","_id":"002"}} {"title": "金都欣欣酒店","city": "天津","price": 200.00,"sup_env":"H5,WX"} {"index":{"_index":"hotel","_id":"003"}} {"title": "金都酒店","city": "北京","price": 500.00,"sup_env":"WX"}
当前用户的客户端为H5或App,当搜索“金都”关键词时应该构建的DSL如下:
GET /hotel/_search { "query": { "bool": { "must": [ { //match查询,使用whitespace分析器 "match": { "title": "金都" } }, { //match查询,使用comma_analyzer分析器 "match": { "sup_env": "H5,APP" } } ] } } }
使用自定义的分词器可以将以逗号分隔的字段进行分词后建立索引,从而在搜索时也使用逗号分隔符进行匹配搜索。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
2020-12-10 定时清理mysql表数据