解决 SpringBoot Elasticsearch 7.x 聚合查询遇到的问题

SpringBoot Elasticsearch 7.x 聚合查询遇到的问题

    • 1. 时间的问题
    • 2. 无法进行聚类的问题
      • 2.1 解决
    • 3. 类型转换的问题
    • 4. QueryBuilders.termQuery() 查询无数据的问题
      • 4.1 解决

 

1. 时间的问题

报错
java.time.DateTimeException: Unable to obtain Instant from TemporalAccessor: {},ISO resolved to 2019-04-30T16:00 of type java.time.format.Parsed

解决:
POJO 类中 Date 类型转化为 LocalDate 类型.

    // 创建时间
    @Field(type = FieldType.Date, format = DateFormat.date_hour_minute_second)
    private LocalDate createTime;

    // 更新时间
    @Field(type = FieldType.Date, format = DateFormat.date_hour_minute_second)
    private LocalDate updateTime;

如果还报错可以将 Date 类型转化为 LocalDate 类型.

在这里插入图片描述

先试第一个再试第二个.
开始 Date 不好使, 之后我是试了 LocalDate 第二个不好使, 试第一个好使.

2. 无法进行聚类的问题

报错
org.springframework.data.elasticsearch.UncategorizedElasticsearchException: Elasticsearch exception [type=search_phase_execution_exception, reason=all shards failed]; nested exception is ElasticsearchStatusException[Elasticsearch exception [type=search_phase_execution_exception, reason=all shards failed]]; nested: ElasticsearchException[Elasticsearch exception [type=illegal_argument_exception, reason=Text fields are not optimised for operations that require per-document field data like aggregations and sorting, so these operations are disabled by default. Please use a keyword field instead. Alternatively, set fielddata=true on [categoryName] in order to load field data by uninverting the inverted index. Note that this can use significant memory.]]; nested: ElasticsearchException[Elasticsearch exception [type=illegal_argument_exception, reason=Text fields are not optimised for operations that require per-document field data like aggregations and sorting, so these operations are disabled by default. Please use a keyword field instead. Alternatively, set fielddata=true on [categoryName] in order to load field data by uninverting the inverted index. Note that this can use significant memory.]];

报错中有这样一句:set fielddata=true on [categoryName]

2.1 解决

在 POJO 类中添加:fielddata=true

解决 SpringBoot Elasticsearch 7.x 聚合查询遇到的问题_第1张图片

    @Field(type = FieldType.Keyword, fielddata=true)
    private String categoryName;

上面添加了 FieldType.Keyword 不分词
用 Kibana 查看发现:不分词可以用 categoryName.keyword

解决 SpringBoot Elasticsearch 7.x 聚合查询遇到的问题_第2张图片
在这里插入图片描述

如果想让 categoryName 分词进行聚类:
需要添加:"fielddata": true

解决 SpringBoot Elasticsearch 7.x 聚合查询遇到的问题_第3张图片

3. 类型转换的问题

报错
java.lang.ClassCastException: class org.elasticsearch.search.aggregations.bucket.terms.ParsedStringTerms cannot be cast to class org.elasticsearch.search.aggregations.bucket.terms.StringTerms (org.elasticsearch.search.aggregations.bucket.terms.ParsedStringTerms and org.elasticsearch.search.aggregations.bucket.terms.StringTerms are in unnamed module of loader 'app')

报错中是无法转化成 StringTerms 类型.
在之前的版本中是可以的, 但在 7 版本以上就不好使了.
需要将 StringTerms 类型改为 Terms 类型.

解决 SpringBoot Elasticsearch 7.x 聚合查询遇到的问题_第4张图片

        // 获取分组数据
        Terms terms = Objects.requireNonNull(searchSkuInfo.getAggregations()).get(termsId);

4. QueryBuilders.termQuery() 查询无数据的问题

用 QueryBuilders.termQuery() 查询没有数据.

原因第一个可能是中文的缘故. 这时候可以用英文试一试. 需中文查询还需要解决.

原因第二个可能是含义没有弄清楚. QueryBuilders.termQuery() 精准匹配, 不进行分词, 也不是模糊匹配, 是完全匹配才可以好使. 而且只支持单个添加, 多个条件需要用 QueryBuilders.termsQuery().

原因第三个可能是 Java Rest Client 客户端自带的 bug.

4.1 解决

方法一:
可以将 QueryBuilders.termQuery(name, value) 中的 name 加上 .keyword.

方法二:
可以将 QueryBuilders.termQuery() 直接用 QueryBuilders.matchPhraseQuery() 代替.
QueryBuilders.matchPhraseQuery() 也是进行精准匹配, match 查询是高级查询, 底层使用了 term 查询.

posted @ 2021-06-08 13:13  a-du  阅读(3937)  评论(2编辑  收藏  举报