ES黑马旅游案例

1、搜索、分页

1、前端会传page和pageSize,即当前页码和页容量,可以通过(page - 1)*size计算偏移量以确定需要展示的数据

2、搜索可以直接找到创建索引库时特地额外增加的all字段进行匹配

2、条件过滤

1、城市、品牌、星级、价格范围,每个条件都要做健壮性判断,即只有在有需要的时候才运行。其中前三者是精确匹配,得用termQuery,价格是范围匹配,得用rangeQuery

3、距离排序

1、在前端传过来定位的时候,需要在查询中添加定位信息,es会根据定位返回与文档中的定位的距离值。在得到查询结果后,获取距离值放到返回对象中以便前端展示。

4、置顶

1、需要保证es文档中有标识置顶因素的索引,比如isAD:true

2、在后端向索引库查询数据的时候,可以判断其是否带有该置顶标识

3、如带有置顶标识,则执行相应的算分控制,以提高其在前端展示中的权重

全程代码如下:

java 复制代码
@Service
public class HotelService extends ServiceImpl<HotelMapper, Hotel> implements IHotelService {
    @Autowired
    private RestHighLevelClient client;
    @Override
    public PageResult search(RequestParams pageParams) {
        try {
            //1.准备Request
            SearchRequest request = new SearchRequest("hotel");
            //2.准备dsl
            //构建dsl
            buildBasicQuery(pageParams,request);
            //价格排序
//            request.source().sort("price", SortOrder.ASC);
            //距离排序
            if(pageParams.getLocation()!=null && !pageParams.getLocation().equals("")){
                request.source().sort(
                        SortBuilders.geoDistanceSort("location",new GeoPoint(pageParams.getLocation()))
                                .order(SortOrder.ASC)
                                .unit(DistanceUnit.KILOMETERS));
            }
            //构建分页
            int page = pageParams.getPage();
            int size = pageParams.getSize();
            request.source().from((page - 1)*size).size(size);
            //3.发送请求,得到响应
            SearchResponse response = client.search(request, RequestOptions.DEFAULT);
            //4.解析响应
            return extracted(response);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }

    private static void buildBasicQuery(RequestParams pageParams,SearchRequest request) {
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        //关键字检索
        String key = pageParams.getKey();
        if (key == null || "".equals(key)) {
            boolQuery.must(QueryBuilders.matchAllQuery());
        }else{
            boolQuery.must(QueryBuilders.matchQuery("all",key));
        }
        //城市
        if (pageParams.getCity() != null && !pageParams.getCity().equals("")) {
            boolQuery.filter(QueryBuilders.termQuery("city", pageParams.getCity()));
        }
        //品牌
        if (pageParams.getBrand() != null && !pageParams.getBrand().equals("")) {
            boolQuery.filter(QueryBuilders.termQuery("brand", pageParams.getBrand()));
        }
        //星级
        if (pageParams.getStarName() != null && !pageParams.getStarName().equals("")) {
            boolQuery.filter(QueryBuilders.termQuery("starName", pageParams.getStarName()));
        }
        //价格范围
        if (pageParams.getMaxPrice() != null && pageParams.getMinPrice()!=null) {
            boolQuery.filter(QueryBuilders.rangeQuery("price")
                    .gte(pageParams.getMinPrice()).lte(pageParams.getMaxPrice()));
        }

        //2、算分控制
        FunctionScoreQueryBuilder functionScoreQuery = QueryBuilders.functionScoreQuery(
                //原始查询,相关性算分的查询
                boolQuery,
                //function score的数组
                new FunctionScoreQueryBuilder.FilterFunctionBuilder[]{
                        //其中的一个function score 元素
                        new FunctionScoreQueryBuilder.FilterFunctionBuilder(
                                //过滤条件
                                QueryBuilders.termQuery("isAD",true),
                                //算分函数
                                ScoreFunctionBuilders.weightFactorFunction(Integer.MAX_VALUE)
                        )
                });
        request.source().query(functionScoreQuery);
    }

    private static PageResult extracted(SearchResponse response) {
        //获取返回结果的hites部分
        SearchHits hits = response.getHits();
        //获取hits中的value部分
        long value = hits.getTotalHits().value;
        System.out.println(value);
        //获取hits中的value中的hits部分
        SearchHit[] hits1 = hits.getHits();
        //新建个返回对象的列表以返回对象集合
        List<HotelDoc> list = new ArrayList<>();
        for (SearchHit hit : hits1) {
            String string = hit.getSourceAsString();
            //反序列化
            HotelDoc hotelDoc = JSON.parseObject(string, HotelDoc.class);
            //获取距离值
            Object[] sortValues = hit.getSortValues();
            if (sortValues.length > 0) {
                Object sortValue = sortValues[0];
                hotelDoc.setDistance(sortValue);
            }
            System.out.println(hotelDoc);
            list.add(hotelDoc);
        }
        return new PageResult(value,list);
    }
}
相关推荐
这是程序猿16 小时前
基于java的ssm框架旅游在线平台
java·开发语言·spring boot·spring·旅游·旅游在线平台
xinxunkandian16 小时前
“产品+服务”双升级 苏州金龙引领旅游客运价值变革
旅游
L***一1 天前
中专旅游管理专业职业发展路径探析:多元方向与能力构建
旅游
全栈软件开发1 天前
易优旅游景区景点网站源码
旅游
煎蛋学姐1 天前
SSM旅游资讯信息服务系统的实现04s3n(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面
数据库·旅游·ssm 框架·旅游资讯系统·会员管理
合作小小程序员小小店1 天前
网页开发,在线%新版本旅游管理%系统,基于eclipse,html,css,jquery,servlet,jsp,mysql数据库
java·数据库·eclipse·html·intellij-idea·旅游·jsp
第***月1 天前
烟台开海后海鲜便宜到不敢信
生活·旅游·风景
合作小小程序员小小店4 天前
网页开发,在线%旧版本旅游管理%系统,基于eclipse,html,css,jquery,servlet,jsp,mysql数据库
java·数据库·servlet·eclipse·jdk·旅游·jsp
A***27954 天前
元宇宙在虚拟旅游中的体验
旅游
韩立学长11 天前
基于Springboot的研学旅游服务系统5u416w14(程序、源码、数据库、调试部署方案及开发环境)系统界面展示及获取方式置于文档末尾,可供参考。
数据库·spring boot·旅游