es——java实现基本搜索功能

在输入框输入搜索关键字、点击页面过滤项、翻页、排序都会导致请求发出,查询商品信息:

 

需要实现的功能包括:

  • 关键字搜索

  • 分类、品牌、价格过滤

  • 排序

  • 分页

  • 高亮

  • 竞价排名

接口说明:

 controller层:

/**
     * 关键字搜索,分页
     */
    @PostMapping("/list")
    public PageDTO<ItemDoc> list(@RequestBody RequestParams params){
        log.info("关键字搜索,分页===前后端联通==" + params);
        this.isearchService.list(params);
        return this.isearchService.list(params);
    }

service层:

/**
     * 搜索关键字,分页
     */
    PageDTO<ItemDoc> list(RequestParams params);

service实现类:

 @Autowired
    private RestHighLevelClient client;

    /**
     * 搜索关键字,分页
     */
    @Override
    public PageDTO<ItemDoc> list(RequestParams params) {
        try {
            //准备Request
            SearchRequest request = new SearchRequest("item");
            //设置请求参数
            buildBasicQuery(params, request);
            //排序 sort
            if (!StringUtils.isBlank(params.getSortBy())) {
                if ("sold".equals(params.getSortBy())) {//按评价排序
                    request.source().sort(params.getSortBy(), SortOrder.DESC);
                }
                if ("price".equals(params.getSortBy())) {//按价格排序
                    request.source().sort(params.getSortBy(), SortOrder.ASC);
                }
            }
            //分页
            request.source().from(params.getPage() - 1).size(params.getSize());
            //高亮
            request.source().highlighter(
                    new HighlightBuilder().field("name").requireFieldMatch(false)
            );
            //执行请求
            SearchResponse response = client.search(request, RequestOptions.DEFAULT);
            //解析结果
            PageDTO<ItemDoc> pageDTO = this.processResponse(response);
            return pageDTO;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 解析响应结果
     *
     * @param response
     */
    private PageDTO<ItemDoc> processResponse(SearchResponse response) {
        PageDTO<ItemDoc> pageDTO = new PageDTO<>();
        //酒店数据集合
        List<ItemDoc> list = new ArrayList<ItemDoc>();
        //解析结果
        SearchHits searchHits = response.getHits();
        //获取文档总数量
        TotalHits total = searchHits.getTotalHits();
        pageDTO.setTotal(total.value);
        //获取文档详情
        SearchHit[] hits = searchHits.getHits();
        for (SearchHit hit : searchHits) {
            //文档内容
            String json = hit.getSourceAsString();
            //将json格式转为对象
            ItemDoc itemDoc = JSONObject.parseObject(json, ItemDoc.class);
            //高亮
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            if (!CollectionUtils.isEmpty(highlightFields)) {
                HighlightField highlightField = highlightFields.get("name");
                //高亮处理后的名称
                String highLightName = highlightField.getFragments()[0].string();
                //覆盖之前的名称
                itemDoc.setName(highLightName);
            }
            //将对先加入集合
            list.add(itemDoc);
        }
        pageDTO.setList(list);
        return pageDTO;
    }

/**
     * 查询条件
     *
     * @param params
     * @param request
     */
    private void buildBasicQuery(RequestParams params, SearchRequest request) {
        // 1.构建BooleanQuery
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        // 2.关键字搜索
        if (!StringUtils.isBlank(params.getKey())) {
            boolQuery.must(QueryBuilders.matchQuery("all", params.getKey()));
        } else {
            boolQuery.must(QueryBuilders.matchAllQuery());
        }
        //过滤
        //品牌
        if (!StringUtils.isBlank(params.getBrand())) {
            boolQuery.filter(QueryBuilders.termQuery("brand", params.getBrand()));
        }
        //分类
        if (!StringUtils.isBlank(params.getCategory())) {
            boolQuery.filter(QueryBuilders.termQuery("category", params.getCategory()));
        }
        //价格
        if (params.getMinPrice() != null && params.getMaxPrice() != null) {
            boolQuery.filter(QueryBuilders.rangeQuery("price").gte(params.getMinPrice()).lte(params.getMaxPrice()));
        }

        //复合查询——算分函数查询
        FunctionScoreQueryBuilder functionScoreQueryBuilder = QueryBuilders.functionScoreQuery(
                boolQuery, //原始查询
                new FunctionScoreQueryBuilder.FilterFunctionBuilder[]{
                        new FunctionScoreQueryBuilder.FilterFunctionBuilder(
                                QueryBuilders.termQuery("isAD", true), //过滤条件(符合条件的文档,重新打分)
                                ScoreFunctionBuilders.weightFactorFunction(10) //如何打分
                        )
                }
        ).boostMode(CombineFunction.SUM);//加权规则(新旧得分运算规则)
        //设置整体查询
        request.source().query(functionScoreQueryBuilder);
    }