java.lang.ClassCastException: org.elasticsearch.search.aggregations.bucket.terms.UnmappedTerms cannot be cast to org.elasticsearch.search.aggregations.bucket.terms.StringTerms
方便同學們檢索: 黑馬 樂優商城 leyou-search SearchService.java
先說結論:es中的結構錯誤,存在非String類型,下次碰到直接 GET goods/_search
(圖1 插件kibana)
(圖2)
如何找到錯誤
測試類1:操作系統 測試正常
String getName = "操作系統";
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
//AggregationBuilders:繼承自Object
// queryBuilder.addAggregation(AggregationBuilders.terms("brandAgg")); //error
queryBuilder.addAggregation(AggregationBuilders.terms(getName).field("specs." + getName + ".keyword"));
//new String[]{} 或者null
queryBuilder.withSourceFilter(new FetchSourceFilter(new String[]{},null));
// Page<Item> items = this.itemRepository.search(queryBuilder.build());
AggregatedPage<Goods> items = (AggregatedPage)this.goodsRepository.search(queryBuilder.build());
//根據字段類型強轉 Brand是String,term聚合,所以結果要強轉爲StringTerm類型
StringTerms brandAgg = (StringTerms)items.getAggregation(getName);
// StringTerms.Bucket bucketHUAWEI = brandAgg.getBucketByKey("華爲");
List<StringTerms.Bucket> buckets = brandAgg.getBuckets();
buckets.forEach(bucket -> {
System.out.println(bucket.getKey());
});
測試2:錯誤
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
// 查詢要聚合的規格參數
List<SpecParam> params = this.specificationClient.queryParams(null, 76l, null, true);
params.forEach(param -> {
System.out.println(param.getName());
queryBuilder.addAggregation(AggregationBuilders.terms(param.getName()).field("specs." + param.getName() + ".keyword"));
});
// 執行聚合查詢
AggregatedPage<Goods> goodsPage = (AggregatedPage<Goods>)this.goodsRepository.search(queryBuilder.build());
// 定義一個集合,收集聚合結果集
List<Map<String, Object>> paramMapList = new ArrayList<>();
// 解析聚合查詢的結果集
Map<String, Aggregation> aggregationMap = goodsPage.getAggregations().asMap();
for (Map.Entry<String, Aggregation> entry : aggregationMap.entrySet()) {
Map<String, Object> map = new HashMap<>();
// 放入規格參數名
System.out.println(entry.getKey());
map.put("k", entry.getKey());
// 收集規格參數值
List<Object> options = new ArrayList<>();
// 解析每個聚合
StringTerms terms = (StringTerms)entry.getValue();
// 遍歷每個聚合中桶,把桶中key放入收集規格參數的集合中
terms.getBuckets().forEach(bucket -> options.add(bucket.getKeyAsString()));
map.put("options", options);
System.out.println(map);
paramMapList.add(map);
}
報錯,調試發現在 內存時報錯,隨即查找聚合得到 圖2,發現內存和機身存儲結構不爲String
解決:
修正 Goods結構
又是一波調試發現在buildGoods()
{"4":["白色","金色","玫瑰金"],"12":["3GB"],"13":["16GB"]}
"12":["3GB"] , 這裏12是字符串
specialSpecMap.get(specParam.getId().toString())
del goods 索引庫 重新操作
elasticsearchTemplate.createIndex(Goods.class);
elasticsearchTemplate.putMapping(Goods.class);
導入數據進es