昨天在做项目的时候,测试人员告诉我项目列表页搜索条件有几个完全不起作用了,搜索数据完全为空,搜不到结果。我第一时间在想是不是项目组哪位大佬误删或在刷数据,经过一番排查后发现问题另有出处 — 原来是ES索引结构出错了,


在ElasticSearch 5.x 之后,字符串类型有了重大改动,移除了String类型,而拆分成了两个新类型:“text”类型用于全文搜索,“keyword”类型用于关键词搜索。
他们最大的区别在于是否会利用分词器进行分词。
而在项目中由于使用的ES自动映射功能,导致String类型的数据会分为两个子域映射:Text和Keyword。
Text和Keyword的区别
ElasticSearch 5.0以后,string类型有重大变更,移除了string类型,string字段被拆分成两种新的数据类型: text用于全文搜索的,而keyword用于关键词搜索。 ElasticSearch字符串将默认被同时映射成text和keyword类型,将会自动创建下面的动态映射(dynamic mappings):
java1
2
3
4
5
6
7
8
9
10
11{
"serviceTyoe": {
"type": "text",
"fields": {
"keyword": {
"ignore_above": 256,
"type": "keyword"
}
}
}
}这就是造成部分字段还会自动生成一个与之对应的“.keyword”字段的原因。其中:
text
- 会分词,然后进行索引;
- 支持模糊、精确查询;
- 不支持聚合;
keyword:
- 不进行分词,直接索引;
- 支持模糊、精确查询;
- 支持聚合;
解决方案
- 在创建ES索引时,将String类型数据指定映射成keyword类型。(string类型默认是“analyzed”,如果想映射字段为确切值,只需要设置它为“not_analyzed”);
- 在拼接ES搜索条件时指定搜索字段的类型,如检索“serviceType”字段时指定“serviceType.keyword”;