黑马旅游案例

黑马旅游案例

1.基本搜索和分页

当我们点击搜索时

在这里插入图片描述

1、注入RestHighLevelClient

@Bean
public RestHighLevelClient client(){
    return new RestHighLevelClient(RestClient.builder(HttpHost.create("http://192.168.150.101:9200")));
    
}

2、创建实体类

RequesParams类

@Data
public class RequestParams {
    private String key;
    private Integer page;
    private Integer size;
    private String sortBy;
}

PageResult类

@Data
public class PageResult {
    private Long total;
    private List<HotelDoc> hotels;

    public PageResult() {
    }

    public PageResult(Long total, List<HotelDoc> hotels) {
        this.total = total;
        this.hotels = hotels;
    }
}

3、自定义一个搜索方法

public interface IHotelService extends IService<Hotel> {
    PageResult searchs(RequestParams params);

}
@Service
public class HotelService extends ServiceImpl<HotelMapper, Hotel> implements IHotelService {
    @Autowired
    private RestHighLevelClient client;

    @Override

    public PageResult searchs(RequestParams params) {
    try {
    SearchRequest request = new SearchRequest("hotel");

    //准备dsl
    //根据关键字搜索和分页
    //健壮性判断
    String key = params.getKey();
    if (key == null || "".equals(key)) {
        request.source().query(QueryBuilders.matchAllQuery());
    } else {


        request.source().query(QueryBuilders.matchQuery("all", key));
    }
    //分页
    //页码
    int page = params.getPage();
    int size = params.getSize();
    request.source().from((page - 1) * size).size(size);

    SearchResponse search = client.search(request, RequestOptions.DEFAULT);

    return extracted(search);
}
catch (IOException e){
    throw new RuntimeException(e);
}
    }

    private PageResult extracted(SearchResponse search) {
        //解析结果
        SearchHits hits = search.getHits();

        //获取总条数
        long totalHits = hits.getTotalHits().value;
//        System.err.println("共搜索到"+totalHits+"条数据");

        List<HotelDoc> hotels=new ArrayList<>();

        //文档数组
        SearchHit[] hitsList = hits.getHits();
        //遍历
        for (SearchHit documentFields : hitsList) {
            String sourceAsString = documentFields.getSourceAsString();
            HotelDoc hotelDoc = JSON.parseObject(sourceAsString, HotelDoc.class);
            hotels.add(hotelDoc);

            }
        //封装返回
        return new PageResult(totalHits,hotels);

        }
}

4、创建HotelController类

@RestController
@RequestMapping("/hotel")
public class HotelControlller {

    @Autowired
    private IHotelService hotelService;
    @PostMapping("/list")
    public PageResult search(@RequestBody RequestParams params){
        return hotelService.searchs(params);
    }
}

2.添加条件过滤

在这里插入图片描述

1、修改实体类RequestParams

@Data
public class RequestParams {
    private String key;
    private Integer page;
    private Integer size;
    private String sortBy;

    private String brand;
    private String city;
    private String starName;
    private Integer minPrice;
    private Integer maxPrice;
}

2、修改searchs代码

@Service
public class HotelService extends ServiceImpl<HotelMapper, Hotel> implements IHotelService {
    @Autowired
    private RestHighLevelClient client;

    @Override

    public PageResult searchs(RequestParams params) {
    try {
    SearchRequest request = new SearchRequest("hotel");

    //准备dsl
        //构建BooleanQuery
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        request.source().query(boolQuery);

        
        //根据关键字搜索和分页
    //健壮性判断

    //分页
    //页码
    int page = params.getPage();
    int size = params.getSize();
    request.source().from((page - 1) * size).size(size);

    SearchResponse search = client.search(request, RequestOptions.DEFAULT);

    return extracted(search);
}
catch (IOException e){
    throw new RuntimeException(e);
}
    }
    
//拆分成一个函数
   private static void buildBasicQuery(RequestParams params, SearchRequest request) {
    BoolQueryBuilder boolQuery=QueryBuilders.boolQuery();
    String key = params.getKey();
    if (key == null || "".equals(key)) {
        boolQuery.must(QueryBuilders.matchAllQuery());
    } else {
        boolQuery.must(QueryBuilders.matchQuery("all", key));
    }
    //条件过滤
    //城市
    if (params.getCity()!=null&&!"".equals(params.getCity())){
        boolQuery.filter(QueryBuilders.termQuery("city", params.getCity()));
    }
    //品牌
    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()));
    }
    //价格范围
    if (params.getMaxPrice()!=null&& params.getMinPrice()!=null){
        //价格过滤
         boolQuery.filter(QueryBuilders.rangeQuery("price").gte(params.getMinPrice()).lte(params.getMaxPrice()));
    }


    request.source().query(boolQuery);
}

    private PageResult extracted(SearchResponse search) {
        //解析结果
        SearchHits hits = search.getHits();

        //获取总条数
        long totalHits = hits.getTotalHits().value;
//        System.err.println("共搜索到"+totalHits+"条数据");

        List<HotelDoc> hotels=new ArrayList<>();

        //文档数组
        SearchHit[] hitsList = hits.getHits();
        //遍历
        for (SearchHit documentFields : hitsList) {
            String sourceAsString = documentFields.getSourceAsString();
            HotelDoc hotelDoc = JSON.parseObject(sourceAsString, HotelDoc.class);
            hotels.add(hotelDoc);

            }
        //封装返回
        return new PageResult(totalHits,hotels);

        }
}

3、附近的酒店

距离排序

显示具体的距离值

在这里插入图片描述

1.在实体类HotelDoc中添加距离属性

private Object distance;

在实体类RequestParams中添加location属性

private String location;

2、编写排序方式

//添加位置排序功能
    String location = params.getLocation();
    if (location!=null&&!location.equals("")){
        request.source().sort(SortBuilders.geoDistanceSort("location",new GeoPoint(location))
                .order(SortOrder.ASC).unit(DistanceUnit.KILOMETERS));
    }

3、修改处理结果

           //获取距离
Object[] sortValues = documentFields.getSortValues();
            if (sortValues.length>0){
                Object sortValue=sortValues[0];
                hotelDoc.setDistance(sortValue);
            }

4、广告置顶功能

在这里插入图片描述

我们需要给置顶的酒店添加一个标记,然后来利用function score给带有指定的文档增加权重

1、在实体类HtmllDoc中

private Boolean isAD;

2、修改设置置顶

POST /hotel/_update/1975922994
{
  "doc": {
    "isAD":true
  }
}

3、修改排序逻辑

private static void buildBasicQuery(RequestParams params, SearchRequest request) {
    BoolQueryBuilder boolQuery=QueryBuilders.boolQuery();
    String key = params.getKey();
    if (key == null || "".equals(key)) {
        boolQuery.must(QueryBuilders.matchAllQuery());
    } else {
        boolQuery.must(QueryBuilders.matchQuery("all", key));
    }
    //条件过滤
    //城市
    if (params.getCity()!=null&&!"".equals(params.getCity())){
        boolQuery.filter(QueryBuilders.termQuery("city", params.getCity()));
    }
    //品牌
    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()));
    }
    //价格范围
    if (params.getMaxPrice()!=null&& params.getMinPrice()!=null){
        //价格过滤
         boolQuery.filter(QueryBuilders.rangeQuery("price").gte(params.getMinPrice()).lte(params.getMaxPrice()));
    }

    //算分控制
    FunctionScoreQueryBuilder functionScoreQueryBuilder = QueryBuilders.functionScoreQuery(
            //原始查询
            boolQuery,
            //function score数组
            new FunctionScoreQueryBuilder.FilterFunctionBuilder[]{
                    //具体的一个function score数组
                    new FunctionScoreQueryBuilder.FilterFunctionBuilder(
                            //满足条件参与算分
                            QueryBuilders.termQuery("isAD",true),
                            ScoreFunctionBuilders.weightFactorFunction(10)
                    )
            });

    request.source().query(functionScoreQueryBuilder);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值