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