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

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