cannot be cast to org.elasticsearch.search.aggregations.bucket.terms.StringTerms
乐优leyou项目第13天
参考:
https://blog.youkuaiyun.com/u010553867/article/details/104452764
解决方案
1.检查数据
2.若为空,删除(DELETE goods)并重新导入数据
导入数据的测试用例
/**
* 导入数据
*/
@Test
public void createIndex() {
// 创建索引
this.elasticsearchTemplate.createIndex(Goods.class);
// 配置映射
this.elasticsearchTemplate.putMapping(Goods.class);
Integer page = 1;
Integer rows = 100;
do {
// 分批查询spuBo
PageResult<SpuBo> pageResult = this.goodsClient.querySpuBoByPage(null, true, page, rows);
// 遍历spubo集合转化为List<Goods>
List<Goods> goodsList = pageResult.getItems().stream().map(spuBo -> {
try {
return this.searchService.buildGoods((Spu) spuBo);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}).collect(Collectors.toList());
this.goodsRepository.saveAll(goodsList);
// 获取当前页的数据条数,如果是最后一页,没有100条
rows = pageResult.getItems().size();
// 每次循环页码加1
page++;
} while (rows == 100);
}
SeachSevice.java(我将buildGoods封装Goods对象的方法换成文档的提供的方法后,elasticsearch中的specs不再为空,怀疑根据视频写的方法有误!)
/**
* 封装Goods对象
*
* @param spu
* @return
* @throws IOException
*/
public Goods buildGoods(Spu spu) throws IOException {
// 创建goods对象
Goods goods = new Goods();
// 查询品牌
Brand brand = this.brandClient.queryBrandById(spu.getBrandId());
// 查询分类名称
List<String> names = this.categoryClient.queryNamesByIds(Arrays.asList(spu.getCid1(), spu.getCid2(), spu.getCid3()));
// 查询spu下的所有sku
List<Sku> skus = this.goodsClient.querySkusBySpuId(spu.getId());
List<Long> prices = new ArrayList<>();
List<Map<String, Object>> skuMapList = new ArrayList<>();
// 遍历skus,获取价格集合
skus.forEach(sku ->{
prices.add(sku.getPrice());
Map<String, Object> skuMap = new HashMap<>();
skuMap.put("id", sku.getId());
skuMap.put("title", sku.getTitle());
skuMap.put("price", sku.getPrice());
skuMap.put("image", StringUtils.isNotBlank(sku.getImages()) ? StringUtils.split(sku.getImages(), ",")[0] : "");
skuMapList.add(skuMap);
});
// 查询出所有的搜索规格参数
List<SpecParam> params = this.specificationClient.queryParams(null, spu.getCid3(), null, true);
// 查询spuDetail。获取规格参数值
SpuDetail spuDetail = this.goodsClient.querySpuDetailBySpuId(spu.getId());
// 获取通用的规格参数
Map<Long, Object> genericSpecMap = MAPPER.readValue(spuDetail.getGenericSpec(), new TypeReference<Map<Long, Object>>() {
});
// 获取特殊的规格参数
Map<Long, List<Object>> specialSpecMap = MAPPER.readValue(spuDetail.getSpecialSpec(), new TypeReference<Map<Long, List<Object>>>() {
});
// 定义map接收{规格参数名,规格参数值}
Map<String, Object> paramMap = new HashMap<>();
params.forEach(param -> {
// 判断是否通用规格参数
if (param.getGeneric()) {
// 获取通用规格参数值
String value = genericSpecMap.get(param.getId()).toString();
// 判断是否是数值类型
if (param.getNumeric()){
// 如果是数值的话,判断该数值落在那个区间
value = chooseSegment(value, param);
}
// 把参数名和值放入结果集中
paramMap.put(param.getName(), value);
} else {
paramMap.put(param.getName(), specialSpecMap.get(param.getId()));
}
});
// 设置参数
goods.setId(spu.getId());
goods.setCid1(spu.getCid1());
goods.setCid2(spu.getCid2());
goods.setCid3(spu.getCid3());
goods.setBrandId(spu.getBrandId());
goods.setCreateTime(spu.getCreateTime());
goods.setSubTitle(spu.getSubTitle());
goods.setAll(spu.getTitle() + brand.getName() + StringUtils.join(names, " "));
goods.setPrice(prices);
goods.setSkus(MAPPER.writeValueAsString(skuMapList));
goods.setSpecs(paramMap);
return goods;
}