ElasticSearch拼音分词
有时我们有允许用户按照拼音搜索的需求,一个解决办法是在插入文档的分词过程中就生成对应的拼音,同时插入进倒排索引。
我们可以使用这个拼音分词插件:medcl/elasticsearch-analysis-pinyin
拼音分词器初步使用#
POST /_analyze
{
"text": ["碳酸钙咀嚼片"],
"analyzer": "pinyin"
}
结果
拼音分词器把每个字都分成了拼音,并把首字母缩写也弄成了一个拼音,这是它在默认情况下的设置。
如果我们要在mapping中直接这样使用这个分词器的话,那么原始的中文将不会被保留,并且如上面一样,使用每个单子的拼音和整个的全拼建立倒排索引,这肯定不是我们所期望的。
分词的三个阶段#
在ElasticSearch中,分词操作实际上有三个阶段,这给了我们自定义不同阶段所使用的分词器的机会
Character Filter
:用于在tokenizer
实际进行分词前对字符流进行处理(比如Html Strip Character Filter
会移除Html标签和特殊字符,只留下文本)Tokenizer
:接收一个字符流,将它们分成独立token,输出一个token流(即实际分词工作)Token Filter
:经常被称为Filter
,它接收tokenizer
的token流,并可以修改(比如转小写),删除(比如移除stopwords)或添加(比如添加同义词)
所以,整个流程就是
Character Filter预处理 -> Tokenizer分词 -> Filter后处理,增删改token
所以,一个看起来更合理的拼音分词策略是在
tokenizer
上使用ik分词器进行正常的中文分词,然后将pinyin分词器用在filter
上,对于ik分词器输出的token流中的每个token,都添加对应的拼音token。
创建自定义分词器#
PUT /test
{
"settings": {
// 分析阶段的设置
"analysis": {
// 分析器设置
"analyzer": {
// 自定义分析器,在tokenizer阶段使用ik_max_word,在filter上使用py
"my_analyzer": {
"tokenizer": "ik_max_word",
"filter": "py"
}
},
// 由于不满足pinyin分词器的默认设置,所以我们基于pinyin
// 自定义了一个filter,叫py,其中修改了一些设置
// 这些设置可以在pinyin分词器官网找到
"filter": {
"py": {
"type": "pinyin",
// 不会这样分:刘德华 > [liu, de, hua]
"keep_full_pinyin": false,
// 这样分:刘德华 > [liudehua]
"keep_joined_full_pinyin": true,
// 保留原始token(即中文)
"keep_original": true,
"limit_first_letter_length": 16,
"remove_duplicated_term": true,
"none_chinese_pinyin_tokenize": false
}
}
}
},
// 定义mapping
"mappings": {
"properties": {
"name": {
"type": "text",
// 使用自定义分词器
"analyzer": "my_analyzer",
}
}
}
}
上面通过一长串定义了我们的自定义分词器,达成了我们的目标,还有值得说的一点是,pinyin分词器的keep_first_letter
的默认值是true,也就是会这样分:刘德华 > [ldh]
测试自定义分词器#
POST /test/_doc/1
{
"id": 1,
"name": "狮子"
}
POST /test/_doc/2
{
"id": 2,
"name": "柿子"
}
GET /test/_search
{
"query": {
"match": {
"name": "shizi"
}
}
}
GET /test/_search
{
"query": {
"match": {
"name": "狮子"
}
}
}
目前还有一个缺陷,是当你查询狮子
时,柿子
也会在结果中:
因为搜索时也会使用my_analyzer
进行分词,所以狮子
会被分成狮子
、shizi
、sz
...当然能匹配到柿子
分离插入和搜索分词器#
"mappings": {
"properties": {
"name": {
"type": "text",
"analyzer": "my_analyzer",
// 搜索时仅使用ik分词器
"search_analyzer": "ik_smart"
}
}
}
作者:Yudoge
出处:https://www.cnblogs.com/lilpig/p/16601737.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
欢迎按协议规定转载,方便的话,发个站内信给我嗷~
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析