cannot be cast to org.elasticsearch.search.aggregations.bucket.terms.StringTerms

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章