es搜索的基本操作(二)

接上文 我们发现要实现多条件查询 只能依靠boolQuery


@Service
public class HotelService extends ServiceImpl<HotelMapper, Hotel> implements IHotelService {

    @Resource
    private HotelMapper hotelMapper;

    @Resource
    private RestHighLevelClient client;

    @Override
    public PageResult search(RequestParams params) throws IOException {
        //准备Request
        SearchRequest request = new SearchRequest("hotel");//操作的数组
        //构建boolQuery组合条件
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        //boolQuery才是搜索条件 其他查询只是boolQuery中的一部分
        request.source().query(boolQuery);
        String key = params.getKey();
        if (key!=null&&key!="") {
           //match查询,会将搜索词分词,再与目标查询字段进行匹配,若分词中的任意一个词与目标字段匹配上,则可查询到。
           boolQuery.must(QueryBuilders.matchQuery("all", key));
        }else {
            //must 中的语句是必须满足的,会影响最终文档的得分
            //filter 中的语句是必须满足的,但是不会影响最终的得分
            //must_not 中的语句是必须不满足的, 不影响最终的得分
            //should中的语句是可以满足的,影响得分,minimum_should_match就是为这兄弟设置的
            boolQuery.must(QueryBuilders.matchAllQuery());
        }
        //城市条件(精确匹配QueryBuilders.termQuery)
        if (params.getCity()!=null&&!"".equals(params.getCity())){
            //termQuery输入的查询内容是什么,就会按照什么去查询,并不会解析查询内容,对它分词。
            boolQuery.filter(QueryBuilders.termQuery("city",params.getCity()));
        }//品牌条件(精确匹配QueryBuilders.termQuery)
        if (params.getBrand()!=null&&!"".equals(params.getBrand())){
            boolQuery.filter(QueryBuilders.termQuery("brand",params.getBrand()));
        }//星级匹配
        if (params.getStarName()!=null&&!"".equals(params.getStarName())){
            boolQuery.filter(QueryBuilders.termQuery("starName",params.getStarName()));
        }
        //价格条件 (范围匹配QueryBuilders.rangeQuery)
        if (params.getMinPrice()!=null&params.getMaxPrice()!=null){
            boolQuery.filter(QueryBuilders.rangeQuery("price")
                    .gte(params.getMaxPrice()).lt(params.getMinPrice()));
                    //gte大于等于 gt大于  lte小于等于 lt小于
        }

        //分页内容
        int page = params.getPage();
        int size = params.getSize();
        //              偏移量 (page-1)*size
        request.source().from((page-1)*size).size(size);

        //发送请求
        SearchResponse search = client.search(request, RequestOptions.DEFAULT);
        return getPageResult(search);
    }

    //对结果进行处理
    private PageResult getPageResult(SearchResponse search) {
        SearchHits searchHits = search.getHits();
        PageResult pageResult = new PageResult();
        pageResult.setTotal(searchHits.getTotalHits().value);
        SearchHit[] hits = searchHits.getHits();
        ArrayList<HotelDoc> list = new ArrayList<>();
        for (SearchHit hit : hits) {
            // 获取文档source
            String json = hit.getSourceAsString();
            // 反序列化
            HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
            // 放入集合
            list.add(hotelDoc);
        }
        pageResult.setHotels(list);
        // 4.4.封装返回
        return  pageResult;
    }



}
要实现多条件查询boolQuery才是搜索条件 其他查询只是boolQuery中的一部分通过判断前端是否传递该数据来实现多条件查询

关于细节我已经写在代码中,条件查询可以抽取成一个方法不会显得代码太臃肿

关于all字段用于拷贝 如果查询多个字段会消耗大量性能 所以拷贝成一个字段all可以提升性能

关于得分 下一章再说

补充:

精确匹配:(用在不能分词的字段keyword等)

精确,指的是查询关键字(或者关键字分词后),必须与目标分词结果完全匹配。 

模糊匹配:(用在可以分词的字段text等)

模糊,是指查询关键字与目标关键字可以模糊匹配。

扩展:范围匹配的api

//闭区间查询
QueryBuilder qb1 = QueryBuilders.rangeQuery("${fieldName}").from(${fieldValue1}).to(${fieldValue2}); 
 
//开区间查询
QueryBuilder qb1 = QueryBuilders.rangeQuery("${fieldName}").from(${fieldValue1}, false).to(${fieldValue2}, false);
 
//大于
QueryBuilder qb1 = QueryBuilders.rangeQuery("${fieldName}").gt(${fieldValue});
 
 //大于等于
QueryBuilder qb1 = QueryBuilders.rangeQuery("${fieldName}").gte(${fieldValue}); 
 
//小于
QueryBuilder qb1 = QueryBuilders.rangeQuery("${fieldName}").lt(${fieldValue}); 
 
//小于等于
QueryBuilder qb1 = QueryBuilders.rangeQuery("${fieldName}").lte(${fieldValue});

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值