本篇文章主要介绍分布式搜索引擎ElasticSearch自定义分词实践。
1、背景
在实际工作中,客户需要使用搜索框对于基金产品或者基金公司信息进行智能化搜索,比如根据基金代码某部分、基金拼音简称等等来搜索符合条件的产品信息,如果使用关系型数据库来进行搜索,那么大概率是采用了全模糊前后%的形式查询,做了全表扫描,那么随着数据量上升,这种方案的代价是很大的,性能和用户体验也是很不好的。
2、解决方案
基于上述场景,我们需要对该场景的搜索性能和用户体验做提升,我们最终选择了分布式搜索引擎ElasticSearch来解决该问题。众所周知,分布式搜索引擎ElasticSearch因其搜索能力强大而出名,且开源社区活跃。
3、具体实践
3.1、自定义分词器
代码语言:javascript复制PUT /product2/
{
"settings":{
"analysis":{
"analyzer":{
"my_analyzer":{
"type":"custom",
"tokenizer":"ik_max_word",
"filter":"my_filter"
}
},
"filter":{
"my_filter":{
"type":"pinyin",
"keep_full_pinyin":true,
"keep_original":true,
"limit_first_letter_length":16,
"lowercase":true,
"keep_first_letter":true,
"keep_separate_first_letter":false
}
}
}
}
}
对自定义分词器进行验证:
代码语言:javascript复制GET /product2/_analyze
{
"text":[
"上投摩根锦程均衡养老目标三年持有期混合型基金中基金(FOF)"
],
"analyzer":"my_analyzer"
}
3.2、ElasticSearch索引映射关系的建立
代码语言:javascript复制POST /product2/_mapping
{
"properties": {
"firstSpellLetter" : {
"type" : "text",
"analyzer" : "my_analyzer"
},
"fullName" : {
"type" : "text",
"analyzer" : "my_analyzer"
},
"liteName" : {
"type" : "text",
"analyzer" : "my_analyzer",
"search_analyzer" : "ik_smart"
},
"productCode" : {
"type" : "text",
"analyzer" : "my_analyzer"
},
"spell" : {
"type" : "text",
"analyzer" : "my_analyzer"
}
}
}
3.3、插入ElasticSearch索引文档
代码语言:javascript复制POST product2/_doc/1
{
"spell":"ShangTouMoGenJinChengJunHengYangLaoSanNianChiYouHunHe(FOF)",
"productCode":"007221",
"firstSpellLetter":"STMGJCJHYLSNCYHH(FOF)",
"fullName":"上投摩根锦程均衡养老目标三年持有期混合型基金中基金(FOF)",
"liteName":"上投摩根锦程均衡养老三年持有混合(FOF)"
}
3.4、根据产品代码进行搜索
搜索结果:
3.5、根据简称进行搜索
搜索结果:
3.6、根据产品全称进行搜索
搜索结果:
3.7、根据产品名称拼音进行搜索
搜索结果:
3.8、根据产品名称拼音简称进行搜索
搜索结果:
结束语:
对于上述的自定义分词,使用了开源的ik分词器和pinyin分词器,ElasticSearch也是支持自定义词典的,按需解决问题即可。
如果你是做产品的,请注意查询和搜索的区别,需要明白哪些场景需要使用查询功能,哪些场景需要使用搜索功能,查询条件的设置等等都会影响用户的体验,同时也会对开发的工作也有一定的价值感。