[Elasticsearch]ES的Mapping设计在实际场景中应用

database

背景

项目中有个需求是需要几个字段作为标签,统计各个标签的文档数量,同时支持分词后的全文检索功能。

原有的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": {

"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.删除原索引,给新索引创建别名(为了代码不动)

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支持全文检索,但是不能进行聚合、排序.

参考

  1. https://doc.codingdict.com/elasticsearch/330/

  2. https://cloud.tencent.com/developer/article/1555004

本文作者: chaplinthink, 关注领域:大数据、基础架构、系统设计, 一个热爱学习、分享的大数据工程师

以上是 [Elasticsearch]ES的Mapping设计在实际场景中应用 的全部内容, 来源链接: utcz.com/z/536191.html

回到顶部