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" -
} -
} -
} -
} -
}
