elasticsearch 实现查询忽略大小写
1 在项目中,产品已经上线一段时间,出现新的需求,需要解决查询的时候,忽略大小写的问题。本人用于测试的索引结构如下PUT test_v1.000{"settings": {"number_of_replicas": 1,"number_of_shards": 5},"mappings": {"product": {"properties": {"name":{"type": "keywor...
·
1 在项目中,产品已经上线一段时间,出现新的需求,需要解决查询的时候,忽略大小写的问题。本人用于测试的索引结构如下
PUT test_v1.000
{
"settings": {
"number_of_replicas": 1,
"number_of_shards": 5
},
"mappings": {
"product": {
"properties": {
"name":{
"type": "keyword"
},
"sex":{
"type": "keyword"
},
"content":{
"type": "text",
"fields": {
"keyword":{
"ignore_above": 32766,
"type": "keyword"
}
}
}
}
}
},
"aliases": {
"test": {}
}
}
2 在test索引里面新增几条数据,用于查询使用
PUT test/product/_bulk
{"index":{"_id":5}}
{ "name": "New York5","sex":"男","content":"ES5.X版本以后,keyword支持的最大长度为32766个UTF-8字节数(至于多少个字符数需要根据业务场景定,建议参考最新版本的官方文档说明),text对字符长度没有限制。New York5"}
{"index":{"_id":6}}
{ "name": "new York6","sex":"男","content":"ES5.X版本以后,keyword支持的最大长度为32766个UTF-8字节数(至于多少个字符数需要根据业务场景定,建议参考最新版本的官方文档说明),text对字符长度没有限制。new York6"}
{"index":{"_id":7}}
{ "name": "New york7","sex":"男","content":"ES5.X版本以后,keyword支持的最大长度为32766个UTF-8字节数(至于多少个字符数需要根据业务场景定,建议参考最新版本的官方文档说明),text对字符长度没有限制。New york7"}
{"index":{"_id":8}}
{ "name": "NEW YORK8","sex":"男","content":"ES5.X版本以后,keyword支持的最大长度为32766个UTF-8字节数(至于多少个字符数需要根据业务场景定,建议参考最新版本的官方文档说明),text对字符长度没有限制。NEW YORK8"}
3 想查询name以及content.keyword里面的数据,但是需要忽略大小写的问题,测试如下,由于此时elasticsearch的mapping未做任何处理,是不会自动忽略大小写的,所以此时下面的查询语句,应该只能查询两条数据,id为2和6的数据。截图如下
POST test/_search
{
"query": {
"bool": {
"must": [
{
"query_string": {
"fields": ["content.keyword","name"],
"query": "*new*"
}
}
]
}
}
}
4 对于elasticsearch查询忽略大小写的问题,官方给出了一个解决方案,使用normalizer来解决,normalizer是keyword的一个属性,可以对keyword生成的单一term,query_string做进一步的处理,比如lowercase,小写转换,使用方式和自定义分词器有相似之处,需要自定义,具体步骤如下。
5 此时由于elasticsearch的索引已经建好,由于es的规则,只能新增字段,不能删除或者修改已经存在的字段,可以动态更新原有索引的setting,动态更新setting,需要先关闭索引,执行玩更新操作以后,再开启索引,步骤如下
POST test/_close
PUT test/_settings
{
"index": {
"analysis": {
"normalizer": {
"lowercase_normalizer": {
"type": "custom",
"char_filter": [],
"filter": [
"lowercase"
]
}
}
}
}
}
POST test/_open
6 查看原有test的索引setting,如下图,发现设置已经生效,这个时候,动态添加新的字段(keyword类型),既可使用lowercase_normalizer,实现忽略大小写的操作。
动态添加一个字段 author,如下,然后查看mapping,发现已经生效,并且author比其他keyword字段多一个属性normalizer
PUT test/product/_mapping
{
"properties": {
"author": {
"type": "keyword",
"normalizer": "lowercase_normalizer"
}
}
}
7 新增一条数据,并且测试,看查询author字段的时候,忽略大小写的操作是否已经实现,具体插入数据不再展示,自行插入数据,查询语句以及结果如下。发现查询da也能将包含DA的数据查询出来,说明已经实现了新增字段忽略大小写的操作。但是对老数据老字段,这种方式并不能解决问题,所以只能新增索引,将老数据同步过去,让我们继续往下操作
8 新建一个新索引,设置normalizer属性,命令如下
PUT xsj_test_v1.000
{
"settings": {
"number_of_replicas": 1,
"number_of_shards": 5,
"analysis": {
"normalizer": {
"lowercase_normalizer": {
"type": "custom",
"char_filter": [],
"filter": [
"lowercase"
]
}
}
}
},
"mappings": {
"product": {
"properties": {
"name":{
"type": "keyword",
"normalizer": "lowercase_normalizer"
},
"sex":{
"type": "keyword",
"normalizer": "lowercase_normalizer"
},
"author":{
"type": "keyword",
"normalizer": "lowercase_normalizer"
},
"content":{
"type": "text",
"fields": {
"keyword":{
"ignore_above": 32766,
"type": "keyword",
"normalizer": "lowercase_normalizer"
}
}
}
}
}
},
"aliases": {
"xsj_test": {}
}
}
9 新建完xsj_test索引以后,同步test的数据过来,命令如下
POST /_reindex
{
"source": {
"index": "test"
},
"dest": {
"index": "xsj_test"
}
}
10 测试name以及content.keyword字段,看是否忽略大小写操作已经生效。查询命令以及结果如下,发现query_string查询的时候,忽略大小写的操作已经生效,并且老数据也可以忽略大小写查询。
POST xsj_test/product/_search
{
"query": {
"bool": {
"must": [
{
"query_string": {
"fields": ["name","author","content.keyword"],
"query": "*new*"
}
}
]
}
}
}
更多推荐
已为社区贡献10条内容
所有评论(0)