[Elasticsearch] ES 的Mapping 设计在实际场景中应用
2021-12-24 14:58
746 查看
背景
项目中有个需求是需要几个字段作为标签,统计各个标签的文档数量,同时支持分词后的全文检索功能。
所使用的ES版本: elasticsearch-5.6.16
原有的mapping设计:
curl -XPUT http://ip:9200/meta_es_metric_data -d' { "settings": { "number_of_shards": 5, "number_of_replicas": 0 }, "mappings": { "meta_metric": { "properties": { "metricCode": { "type": "text", "analyzer" : "ik_max_word" }, "metricTechType": { "type": "keyword" }, "dataDomainName": { "type": "keyword" }, "sceneClassify": { "type": "keyword" }, "metricClassify": { "type": "keyword" } } } } }'
其中keyword类型就是作为标签统计字段,因为其类型不支持分词检索,检索时必须精确查找,我们尝试把其类型修改成text,text本身就是支持分词索引,但是修改后就报错了:
Fielddata is disabled on text fields by default
经过查询了解es一个字段类型被设置为text,再进行聚合统计,就会报上面的问题.
那么ES有没有办法对一个字段支持分词检索同时可以进行统计的特性呢?其实就是ES是否可以一个字段定义两种类型: keyword 和 text?
答案是可以的.
ES字段的fields属性
通过fields属性来让当前字段同时具备keyword和text类型
由于我们本身的字段类型是keyword,那我在field 属性中添加一个text,是否就满足需求呢?如:
curl -XPUT http://ip:9200/meta_es_metric_data -d' { "settings": { "number_of_shards": 5, "number_of_replicas": 0 }, "mappings": { "meta_metric": { "properties": { "metricCode": { "type": "text", "analyzer" : "ik_max_word" }, "metricTechType": { "type": "keyword" "fields": { "raw": { "type": "text" } } } } } } }'
当用match 搜索metricTechType.raw, 分词搜索是不行的。
之所以想这样做是因为ES支持新增字段、更新字段,但是不支持字段类型的修改
这条方法走不通,就比较复杂了,因为考虑修改字段类型,我们只能重建mapping, 同时涉及历史数据的加载处理。
具体步骤
1.重建索引,因es不支持修改字段类型
curl -XPUT http://ip:9200/meta_es_metric_data_new -d' { "settings": { "number_of_shards": 5, "number_of_replicas": 0 }, "mappings": { "meta_metric": { "properties": { "metricCode": { "type": "text", "analyzer" : "ik_max_word" }, "metricTechType": { "type": "text", "fields": { "raw": { "type": "keyword" } } }, "dataDomainName": { 56c "type": "text", "fields": { "raw": { "type": "keyword" } } }, "sceneClassify": { "type": "text", "fields": { "raw": { "type": "keyword" } } }, "metricClassify": { "type": "text", "fields": { "raw": { "type": "keyword" } } } } } } }'
2.查看索引映射
curl -XGET 'http://ip:9200/meta_es_metric_data_new/_mapping'
3.将数据加载到新的索引上(老索引的数据还是在的)
curl -XPOST http://ip:9200/_reindex -d' { "source":{ "index": "meta_es_metric_data" }, "dest": { "index": "meta_es_metric_data_new" } }'
4.查看老索引数据:
curl -XGET 'http://ip:9200/meta_es_metric_data/_search?pretty' -H 'Content-Type: application/json' -d' { "query": { "match": { "dataDomainName": "用户" } } } '
5.删除原 ad8 索引,给新索引创建别名(为了代码不动)
curl -XDELETE http://ip:9200/meta_es_metric_data curl -XPOST http://ip:9200/_aliases -d' { "actions":[ { "add": { "index": "meta_es_metric_data_new", "alias": "meta_es_metric_data" } } ] }'
6.测试字段是否支持全文检索及聚合
curl -XGET 'http://ip:9200/meta_es_metric_data_new/_search?pretty' -H 'Content-Type: application/json' -d' { "query": { "match": { "dataDomainName": "用户" } }, "sort": { "dataDomainName.raw": "asc" }, "aggs": { "Cities": { "terms": { "field": "dataDomainName.raw" } } } } '
总结
本文主要讲解如何让一个字段支持不同方式索引,利用Fields属性. 同时如何对历史存量数据进行处理. keyword类型支持es精确查找以及聚合排序,text支持全文检索,但是不能进行聚合、排序.
参考
相关文章推荐
- 设计模式实际应用场景(转)
- 动态口令设计系列一续:实际应用场景中对动态口令的一些误解
- [置顶] 设计模式-单例模式(Singleton)在Android中的应用场景和实际使用遇到的问题
- 设计模式-单例模式(Singleton)在Android中的应用场景和实际使用遇到的问题
- 设计模式-单例模式(Singleton)在Android中的应用场景和实际使用遇到的问题
- IntentService的实际应用场景
- 设计模式之——单例模式(Singleton)的实现、优缺点和常见应用场景
- 设计模式复习:常用设计模式概念及应用场景
- 设计模式的实际应用
- 23种设计模式分类及各类的典型模式及应用场景(面试会考,必须掌握)
- java Hashcode实际应用场景
- 架构设计:系统间通信(32)——其他消息中间件及场景应用(下2)
- 设计模式的应用场景(19)--访问者模式
- ZooKeeper学习之路 (七)ZooKeeper设计特点及典型应用场景
- 工作流程引擎回滚应用场景与设计需求
- flume的级别的架构使用--实际场景应用--可以用于分布式的服务形式的日志采集
- 设计模式的应用场景(5)--单例模式
- 设计模式之——单例模式(Singleton)的常见应用场景
- 责任链设计模式应用场景示例(过滤器、拦截器)
- Redis实际应用场景