之前1写的是es相关的设计跟dsl语法怎么写(怎么实现京东搜索页面的功能)这个是把dsl语法写成java代码
前端传来的参数映射类
public class ESRequestParam { private String keyword; private ListbrandId; private Long categoryId; private String sort; private Long salecount;//销量 private Date putawayDate;//上架时间 private Integer hasStock; private String price; private List attrs; private Integer pageNum = 1; private String queryString; public String getKeyword() { return keyword; } public void setKeyword(String keyword) { this.keyword = keyword; } public List getBrandId() { return brandId; } public void setBrandId(List brandId) { this.brandId = brandId; } public String getSort() { return sort; } public void setSort(String sort) { this.sort = sort; } public Integer getHasStock() { return hasStock; } public void setHasStock(Integer hasStock) { this.hasStock = hasStock; } public String getPrice() { return price; } public void setPrice(String price) { this.price = price; } public List getAttrs() { return attrs; } public void setAttrs(List attrs) { this.attrs = attrs; } public Integer getPageNum() { return pageNum; } public void setPageNum(Integer pageNum) { this.pageNum = pageNum; } public String getQueryString() { return queryString; } public void setQueryString(String queryString) { this.queryString = queryString; } public Long getCategoryId() { return categoryId; } public void setCategoryId(Long categoryId) { this.categoryId = categoryId; } public Long getSalecount() { return salecount; } public void setSalecount(Long salecount) { this.salecount = salecount; } public Date getPutawayDate() { return putawayDate; } public void setPutawayDate(Date putawayDate) { this.putawayDate = putawayDate; } }
Controller层
@RestController public class MallSearchController { @Autowired private MallSearchService mallSearchService; @ResponseBody @RequestMapping(value = "/searchList") public CommonResultlistPage(ESRequestParam param, HttpServletRequest request) { //1、根据传递来的页面的查询参数,去es中检索商品 ESResponseResult searchResult = mallSearchService.search(param); return CommonResult.success(searchResult); } }
Service层
public interface MallSearchService { ESResponseResult search(ESRequestParam param); }
Service实现类
@Service(value=“mallSearchService”)
public class MallSearchServiceImpl implements MallSearchService {
@Qualifier("restHighLevelClient") @Autowired private RestHighLevelClient client; @Override public ESResponseResult search(ESRequestParam param) { try { //1、构建检索对象-封装请求相关参数信息 SearchRequest searchRequest = startBuildRequestParam(param); //2、进行检索 *** 作 SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT); System.out.println("response:"+response); //3、分析响应数据,封装成指定的格式 ESResponseResult responseResult = startBuildResponseResult(response, param); return responseResult; } catch (Exception e) { e.printStackTrace(); } return null; } private SearchRequest startBuildRequestParam(ESRequestParam param) { SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder(); //1、查询关键字 if (!StringUtils.isEmpty(param.getKeyword())) { //单字段查询 //boolQueryBuilder.must(QueryBuilders.matchQuery("name", param.getKeyword())); //多字段查询 boolQueryBuilder.must(QueryBuilders.multiMatchQuery(param.getKeyword(),"name","keywords","subTitle")); } //2、根据类目ID进行过滤 if (null != param.getCategoryId()) { boolQueryBuilder.filter(QueryBuilders.termQuery("categoryId", param.getCategoryId())); } //3、根据品牌ID进行过滤 if (null != param.getBrandId() && param.getBrandId().size() > 0) { boolQueryBuilder.filter(QueryBuilders.termsQuery("brandId", param.getBrandId())); } //4、根据属性进行相关过滤 if (param.getAttrs() != null && param.getAttrs().size() > 0) { param.getAttrs().forEach(item -> { //attrs=1_白色&2_4核 BoolQueryBuilder boolQuery = QueryBuilders.boolQuery(); //attrs=1_64G String[] s = item.split("_"); String attrId = s[0]; String[] attrValues = s[1].split(":");//这个属性检索用的值 boolQuery.must(QueryBuilders.termQuery("attrs.attrId", attrId)); boolQuery.must(QueryBuilders.termsQuery("attrs.attrValue", attrValues)); NestedQueryBuilder nestedQueryBuilder = QueryBuilders.nestedQuery("attrs", boolQuery, ScoreMode.None); boolQueryBuilder.filter(nestedQueryBuilder); }); } //5、是否有库存 if (null != param.getHasStock()) { boolQueryBuilder.filter(QueryBuilders.termQuery("hasStock", param.getHasStock() == 1)); } //6、根据价格过滤 if (!StringUtils.isEmpty(param.getPrice())) { //价格的输入形式为:10_100(起始价格和最终价格)或_100(不指定起始价格)或10_(不限制最终价格) RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("price"); String[] price = param.getPrice().split("_"); if (price.length == 2) { //price: _5000 if (param.getPrice().startsWith("_")) { rangeQueryBuilder.lte(price[1]); } else{ //price: 1_5000 rangeQueryBuilder.gte(price[0]).lte(price[1]); } } else if (price.length == 1) { //price: 1_ if (param.getPrice().endsWith("_")) { rangeQueryBuilder.gte(price[0]); } } boolQueryBuilder.filter(rangeQueryBuilder); } //封装所有查询条件 searchSourceBuilder.query(boolQueryBuilder); //排序 //页面传入的参数值形式 sort=price_asc/desc if (!StringUtils.isEmpty(param.getSort())) { String sort = param.getSort(); String[] sortFileds = sort.split("_"); if(!StringUtils.isEmpty(sortFileds[0])){ SortOrder sortOrder = "asc".equalsIgnoreCase(sortFileds[1]) ? SortOrder.ASC : SortOrder.DESC; searchSourceBuilder.sort(sortFileds[0], sortOrder); } } //分页查询 searchSourceBuilder.from((param.getPageNum() - 1) * SearchConstant.PAGE_SIZE); searchSourceBuilder.size(SearchConstant.PAGE_SIZE); //高亮显示 if (!StringUtils.isEmpty(param.getKeyword())) { HighlightBuilder highlightBuilder = new HighlightBuilder(); highlightBuilder.field("name"); highlightBuilder.preTags(""); highlightBuilder.postTags(""); searchSourceBuilder.highlighter(highlightBuilder); } //1. 按照品牌进行聚合 TermsAggregationBuilder brand_agg = AggregationBuilders.terms("brand_agg"); brand_agg.field("brandId").size(50); //1.1 品牌的子聚合-品牌名聚合 brand_agg.subAggregation(AggregationBuilders.terms("brand_name_agg").field("brandName").size(1)); //1.2 品牌的子聚合-品牌图片聚合 brand_agg.subAggregation(AggregationBuilders.terms("brand_img_agg").field("brandImg").size(1)); searchSourceBuilder.aggregation(brand_agg); //2. 按照分类信息进行聚合 TermsAggregationBuilder category_agg = AggregationBuilders.terms("category_agg"); category_agg.field("categoryId").size(50); category_agg.subAggregation(AggregationBuilders.terms("category_name_agg").field("categoryName").size(1)); searchSourceBuilder.aggregation(category_agg); //2. 按照属性信息进行聚合 NestedAggregationBuilder attr_agg = AggregationBuilders.nested("attr_agg", "attrs"); //2.1 按照属性ID进行聚合 TermsAggregationBuilder attr_id_agg = AggregationBuilders.terms("attr_id_agg").field("attrs.attrId"); attr_agg.subAggregation(attr_id_agg); //2.1.1 在每个属性ID下,按照属性名进行聚合 attr_id_agg.subAggregation(AggregationBuilders.terms("attr_name_agg").field("attrs.attrName").size(1)); //2.1.1 在每个属性ID下,按照属性值进行聚合 attr_id_agg.subAggregation(AggregationBuilders.terms("attr_value_agg").field("attrs.attrValue").size(50)); searchSourceBuilder.aggregation(attr_agg); System.out.println("构建的DSL语句 {}:"+ searchSourceBuilder.toString()); SearchRequest searchRequest = new SearchRequest(new String[]{SearchConstant.INDEX_NAME}, searchSourceBuilder); return searchRequest; } private ESResponseResult startBuildResponseResult(SearchResponse response, ESRequestParam param) { ESResponseResult result = new ESResponseResult(); //1、获取查询到的商品信息 SearchHits hits = response.getHits(); ListesModels = new ArrayList<>(); //2、遍历所有商品信息 if (hits.getHits() != null && hits.getHits().length > 0) { for (SearchHit hit : hits.getHits()) { String sourceAsString = hit.getSourceAsString(); EsProduct esModel = JSON.parseObject(sourceAsString, EsProduct.class); //2.1 判断是否按关键字检索,若是就显示高亮,否则不显示 if (!StringUtils.isEmpty(param.getKeyword())) { //2.2 拿到高亮信息显示标题 HighlightField name = hit.getHighlightFields().get("name"); //2.3 判断name中是否含有查询的关键字(因为是多字段查询,因此可能不包含指定的关键字,假设不包含则显示原始name字段的信息) String namevalue = name!=null ? name.getFragments()[0].string() : esModel.getName(); esModel.setName(namevalue); } esModels.add(esModel); } } result.setProducts(esModels); //3、当前商品涉及到的所有品牌信息,小米手机和小米电脑都属于小米品牌,过滤重复品牌信息 List brandVos = new ArrayList<>(); //获取到品牌的聚合 ParsedLongTerms brandAgg = response.getAggregations().get("brand_agg"); for (Terms.Bucket bucket : brandAgg.getBuckets()) { ESResponseResult.BrandVo brandVo = new ESResponseResult.BrandVo(); //获取品牌的id long brandId = bucket.getKeyAsNumber().longValue(); brandVo.setBrandId(brandId); //获取品牌的名字 ParsedStringTerms brandNameAgg = bucket.getAggregations().get("brand_name_agg"); String brandName = brandNameAgg.getBuckets().get(0).getKeyAsString(); brandVo.setBrandName(brandName); //获取品牌的LOGO ParsedStringTerms brandImgAgg = bucket.getAggregations().get("brand_img_agg"); String brandImg = brandImgAgg.getBuckets().get(0).getKeyAsString(); brandVo.setBrandImg(brandImg); System.out.println("brandId:"+brandId+"brandName:"+brandName+"brandImg"); brandVos.add(brandVo); } System.out.println("brandVos.size:"+brandVos.size()); result.setBrands(brandVos); //4、当前商品相关的所有类目信息 //获取到分类的聚合 List categoryVos = new ArrayList<>(); ParsedLongTerms categoryAgg = response.getAggregations().get("category_agg"); for (Terms.Bucket bucket : categoryAgg.getBuckets()) { ESResponseResult.categoryVo categoryVo = new ESResponseResult.categoryVo(); //获取分类id String keyAsString = bucket.getKeyAsString(); categoryVo.setCategoryId(Long.parseLong(keyAsString)); //获取分类名 ParsedStringTerms categoryNameAgg = bucket.getAggregations().get("category_name_agg"); String categoryName = categoryNameAgg.getBuckets().get(0).getKeyAsString(); categoryVo.setCategoryName(categoryName); categoryVos.add(categoryVo); } result.setCategorys(categoryVos); //5、获取商品相关的所有属性信息 List attrVos = new ArrayList<>(); //获取属性信息的聚合 ParsedNested attrsAgg = response.getAggregations().get("attr_agg"); ParsedLongTerms attrIdAgg = attrsAgg.getAggregations().get("attr_id_agg"); for (Terms.Bucket bucket : attrIdAgg.getBuckets()) { ESResponseResult.AttrVo attrVo = new ESResponseResult.AttrVo(); //获取属性ID值 long attrId = bucket.getKeyAsNumber().longValue(); attrVo.setAttrId(attrId); //获取属性的名字 ParsedStringTerms attrNameAgg = bucket.getAggregations().get("attr_name_agg"); String attrName = attrNameAgg.getBuckets().get(0).getKeyAsString(); attrVo.setAttrName(attrName); //获取属性的值 ParsedStringTerms attrValueAgg = bucket.getAggregations().get("attr_value_agg"); System.out.println("===1==="+attrValueAgg.getBuckets()); for (Terms.Bucket b : attrValueAgg.getBuckets()) { String bb = b.getKeyAsString(); System.out.println("bb:"+bb); } List attrValues = attrValueAgg.getBuckets().stream().map(item -> item.getKeyAsString()).collect(Collectors.toList()); attrVo.setAttrValue(attrValues); System.out.println("===2==="+attrValues); attrVos.add(attrVo); } result.setAttrs(attrVos); //6、进行分页 *** 作 result.setPageNum(param.getPageNum()); //获取总记录数 long total = hits.getTotalHits().value; result.setTotal(total); //计算总页码 int totalPages = (int) total % SearchConstant.PAGE_SIZE == 0 ? (int) total / SearchConstant.PAGE_SIZE : ((int) total / SearchConstant.PAGE_SIZE + 1); result.setTotalPages(totalPages); List pageNavs = new ArrayList<>(); for (int i = 1; i <= totalPages; i++) { pageNavs.add(i); } result.setPageNavs(pageNavs); return result; } }
es依赖版本
7.6.1 org.springframework.boot spring-boot-starter-data-elasticsearch
java代码都是对照dsl语句写的 es依赖提供了所有api 要我们自己根据dsl语句一个一个的拼装
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)