1.最近在使用spring-data-elasticsearch时碰到一个问题,当查询字段是字符串时,并且传入的子串带有大写字母,这时候使用term精确查询无论字段类型是keyword还是text都是查询不到结果的,但是使用match却可以查到结果
2.各方查找资料得知乃是elasticsearch在创建倒排索引时,就已经将大写转为小写,而后写入索引;
ES的建立索引过程:分词->语法处理(还原时态等等)->排序->创建索引。
3.目前有两种解决办法相对比较方便处理:
一种是在传入查询条件的时候,使用toLowerCase()转化为小写,但是条件一多,代码量颇多,不太适用。一种是在设置mapping的时候设置normalizer
如果创建index时mapping没有指定某个filed的标准化配置normalizer,那么如果写入ES的是大写,搜索出来看到的结果也是大写,但是创建的索引却是小写(可以用分词验证),以至于搜索的时候使用term会失败。
比如我的mapping为(内部使用,非完整mapping,重要是看字段):
-
"mappings": {
-
"rack_crm_community_type": {
-
"dynamic": "false",
-
"_all": {
-
"enabled": false
-
},
-
"properties": {
-
"claimBdPin": {
-
"type": "string"
-
},
-
"createBdPin": {
-
"type": "string"
-
},
-
"city": {
-
"type": "integer"
-
},
-
"communityStatusCode": {
-
"type": "integer"
-
},
-
"communityName": {
-
"analyzer": "ik_max_word",
-
"type": "string"
-
},
-
"location": {
-
"type": "geo_point"
-
},
-
"communityId": {
-
"type": "long"
-
},
-
"communityPersonNum": {
-
"type": "integer"
-
},
-
"claimTime": {
-
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis",
-
"type": "date"
-
}
-
}
-
}
-
}
以"claimBdPin"字段为例,只是指定了String类型。存储结果为:
当搜索条件为:
-
{
-
"query":{
-
"bool":{
-
"filter":[
-
{"term": {"claimBdPin":"KA_liulin"}}
-
]
-
}
-
}
-
}
结果为空。
当搜索条件为:
-
{
-
"query":{
-
"bool":{
-
"must":[
-
{"match": {"claimBdPin":"KA_liulin"}}
-
]
-
}
-
}
-
}
结果为:
能查询到,为什么呢?测试分词(ik_max_word)发现:KA_liulin分词为ka_liulin、ka、liulin三个分词。虽然存储的是KA_liulin,但是因为建立索引的时候会自动进行处理为ka_liulin(因为mapping未做分词),再创建索引。match查询的时候,会自动对参数进行处理,所以match搜索的时候使用KA_liulin(实际搜索为ka_liulin)能查询到,而term则查询不到。
因为mapping时未设置分词,所以一般使用term(过滤)来查询,所以要么在代码里面使用String.toLowerCase,但是太麻烦,那么要怎么一次性解决问题呢?我们可以mapping的时候设置normalizer(normalizer用于解析前的标准化配置,比如把所有的字符转化为小写等)
https://www.elastic.co/guide/en/elasticsearch/reference/6.1/normalizer.html
-
PUT index
-
{
-
"settings": {
-
"analysis": {
-
"normalizer": {
-
"my_normalizer": {
-
"type": "custom",
-
"char_filter": [],
-
"filter": ["lowercase", "asciifolding"]
-
}
-
}
-
}
-
},
-
"mappings": {
-
"type": {
-
"properties": {
-
"foo": {
-
"type": "keyword",
-
"normalizer": "my_normalizer"
-
}
-
}
-
}
-
}
-
}