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
@Field(type = FieldType.Keyword, fielddata=true) private String categoryName;
上面添加了
FieldType.Keyword
不分詞
用 Kibana 查看發現:不分詞可以用categoryName.keyword
如果想讓 categoryName 分詞進行聚類:
需要添加:"fielddata": true
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
類型.
// 獲取分組數據 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 查詢.