使用normalizer优化keyword字段的查询
我们知道elasticsearch提供了很多的字段类型,当我们索引结构化的简单字段的时候可以使用keyword类型,例如id,email、主机名、状态码、标签、邮政编码等;
但是keyword字段类型在索引的时候,并不会对字段的值进行一些预处理,也就是直接保留字段的原值。
当我们使用如下文档进行索引的时候,es到底是怎样进行索引处理的呢?
{
"id":1,
"name":"code"
}
Es字段的索引是通过对应类型的mapper进行处理,通过KeywordFieldMapper的parseCreateField的396行可以看到索引的时候,es直接将name字段的value即”code”作为二进制保存,没有进行任何的处理。
当我使用如下的查询语句进行查询的时候,es是怎么来构建查询语句的呢?
{
"query":{
"term":{
"name":"code"
}
}
}
Es首先会获取name字段对应的字段类型,然后调用字段的termQuery来构建查询语句;
这里name字段对应的是KeywordFieldMapper,其并没有覆盖实现父类的的termQuery方法,所以直接执行父类TermBasedFieldType的对应方法,方法中使用indexedValueForSearch对查询关键字进行处理;
我们可以看到KeywordFieldMapper实现了indexedValueForSearch, 由于初始化的时候将search/index的Analyzer都设置为Lucene.KEYWORD_ANALYZER,所以这里会执行305行调用父类TermBasedFieldType的indexedValueForSearch。
我们可以看到父类TermBasedFieldType也未对value进行任何的处理;
这样会带来一个问题,如果字段对应的值并不是枚举类型,而是用户输入的标签等,如果用户输入的单词包含大小写,那么搜索的时候也必须输入一模一样的关键字,否则使用下边的查询语句是命中不了结果的;
{
"query":{
"term":{
"name":"Code"
}
}
}
通过查询es的文档,我们可以看到keyword类型提供了一个normalizer的配置参数,可以在index之前进行一些预处理工作;在自定义的normalizer中可以定义character filters和token filters,这样我们可以像下边这样配置一个lowercase的token filters即可以实现忽略大小写。
{
"settings":{
"analysis":{
"normalizer":{
"lowercase_normalizer":{
"type":"custom",
"filter":[
"lowercase"
]
}
}
}
},
"mappings":{
"_doc":{
"properties":{
"id":{
"type":"integer"
},
"name":{
"type":"keyword",
"normalizer":"lowercase_normalizer"
}
}
}
}
}
在CustomNormalizerProvider中我们可以看到解析配置的char filters和token filters,并组合生成Custome analyzer。
在生成name字段的mapper的时候,根据配置的normalizer name获取对象的对象,并设置为field type的normalizer和search analyzer。
当我们index下边的文档的时候,我们看下es是怎么处理的
{
"id":1,
"name":"Code"
}
可以看到index文档的时候,会获取keyword对应的field type的normalizer,然后对name字段的value进行处理。
当我们搜索的时候,由于已经重置了keyword 对应的field type的searchAnalyzer,所以会直接调用新的自定的normalizer的normalize对输入的关键字进行与处理。
最终不管我们输入的name的值大小写的形式怎样,我们都可以搜索到
相关文章
- 金融服务领域的大数据:即时分析
- 影响大数据、机器学习和人工智能未来发展的8个因素
- 从0开始构建一个属于你自己的PHP框架
- 如何将Hadoop集成到工作流程中?这6个优秀实践必看
- SEO公司使用大数据优化其模型的5种方法
- 关于Web Workers你需要了解的七件事
- 深入理解HTTPS原理、过程与实践
- 增强分析:数据和分析的未来
- PHP协程实现过程详解
- AI专家:大数据知识图谱——实战经验总结
- 关于PHP的错误机制总结
- 利用数据分析量化协同过滤算法的两大常见难题
- 怎么做大数据工作流调度系统?大厂架构师一语点破!
- 2019大数据处理必备的十大工具,从Linux到架构师必修
- OpenCV中的KMeans算法介绍与应用
- 教大家如果搭建一套phpstorm+wamp+xdebug调试PHP的环境
- CentOS下三种PHP拓展安装方法
- Go语言HTTP Server源码分析
- Go语言HTTP Server源码分析
- 2017年4月编程语言排行榜:Hack首次进入前五十