关于ES字符串类型的选择
ElasticSearch 5.0以后,string类型有重大变更,移除了string
类型,string
字段被拆分成两种新的数据类型: text
用于全文搜索的,而keyword
用于关键词搜索。
ElasticSearch字符串将默认被同时映射成text
和keyword
类型,将会自动创建下面的动态映射(dynamic mappings):
{ "foo": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } } } |
这就是造成部分字段还会自动生成一个与之对应的“.keyword”字段的原因。
Text vs. keyword
Text:会分词,然后进行索引
支持模糊、精确查询
不支持聚合
keyword:不进行分词,直接索引
支持模糊、精确查询
支持聚合
由于接口中有的需要源字段,而有的需要keyword字段,需要前后端做判断,十分繁琐且很难保持接口统一。
测试
Mapping
{ "order": 0, "version": 50001, "template": "test", "settings": { "index": { "refresh_interval": "5s" } }, "mappings": { "website": { "_all": { "norms": false, "enabled": true }, "properties": { "@timestamp": { "include_in_all": false, "type": "date" }, "keytrue": { "index": true, "type": "keyword" }, "keyfalse": { "index": false, "type": "keyword" }, "textfalse": { "index": false, "type": "text" }, "texttrue": { "index": true, "type": "text" } } } }, "aliases": {} } |
Data
PUT /test/test/1 { "@timestamp":1511147712941, "keytrue":"test keytrue", "keyfalse":"test keyfalse", "texttrue":"test texttrue", "textfalse":"test textfalse" } |
Index Patterns
name |
| format | searchable | aggregatable | |
keyfalse | string |
|
| √ | |
keytrue | string |
| √ | √ | |
textfalse | string |
|
|
| |
textfalse.keyword | string |
| √ | √ | |
texttrue | string |
| √ |
| |
texttrue.keyword | string |
| √ | √ |
搜索结果
条件 |
| |
keytrue : "test keytrue" | √ | |
keytrue : "test" |
| |
keyfalse |
| |
textfalse |
| |
textfalse.keyword : "test textfalse" | √ | |
textfalse.keyword : "test" |
| |
texttrue : "test texttrue" | √ | |
texttrue : "test" | √ | |
texttrue.keyword : "test texttrue " | √ | |
texttrue.keyword : "test" |
|
结论
keyword类型满足目前系统的需求,且能保证接口统一,所以建议将查询、聚合中涉及的字符串类型,在mapping中设置为“keyword”。