ElasticSearch搜索时match和term大小写问题

https://blog.csdn.net/Java_Beginner27/article/details/81127102

 

ES的建立索引过程:分词->语法处理(还原时态等等)->排序->创建索引。

其他暂不讨论,本文只讨论大小写问题。

如果创建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"
        }
      }
    }
  }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在使用Spring集成Elasticsearch7,可以通过设置索引的映射和查询使用的分析器来实现忽略大小写的功能。 首先,在创建索引,可以使用字段的映射设置来指定对应字段的分析器。通过设置分析器为"keyword_lowercase",可以将字段设置为忽略大小写。例如,以下代码片段演示了如何创建一个忽略大小写的索引: ```java CreateIndexRequest createIndexRequest = new CreateIndexRequest("my_index"); createIndexRequest.settings(Settings.builder() .put("index.analysis.analyzer.default.type", "custom") .put("index.analysis.analyzer.default.tokenizer", "keyword") .put("index.analysis.analyzer.default.filter", "lowercase") .build()); Mapping mapping = new Mapping.Builder() .field(new StringField("my_field") .analyzer("keyword_lowercase")) .build(); createIndexRequest.mapping(mapping); CreateIndexResponse response = restHighLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT); ``` 在查询,我们可以使用Spring Data Elasticsearch来构造查询请求。通过使用`QueryBuilders`类提供的`matchQuery`方法,并指定字段为忽略大小写的分析器,可以实现忽略大小写的查询。例如,以下代码片段演示了如何使用忽略大小写的方式进行查询: ```java QueryBuilder queryBuilder = QueryBuilders.matchQuery("my_field", "value") .analyzer("keyword_lowercase"); SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); searchSourceBuilder.query(queryBuilder); SearchRequest searchRequest = new SearchRequest("my_index"); searchRequest.source(searchSourceBuilder); SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT); ``` 通过以上的设置和方法,我们可以在Spring集成Elasticsearch7中实现忽略大小写的功能。这样,无论字段的大小写如何,都可以正确地进行索引和查询操作。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值