package cn.itcast.hotel.service.impl; import cn.itcast.hotel.constant.EsConstant; import cn.itcast.hotel.mapper.HotelMapper; import cn.itcast.hotel.pojo.Hotel; import cn.itcast.hotel.pojo.HotelDoc; import cn.itcast.hotel.pojo.PageResult; import cn.itcast.hotel.pojo.SearchParams; import cn.itcast.hotel.service.IHotelService; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.apache.commons.lang3.StringUtils; import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.common.geo.GeoPoint; import org.elasticsearch.common.lucene.search.function.CombineFunction; import org.elasticsearch.common.unit.DistanceUnit; import org.elasticsearch.index.query.BoolQueryBuilder; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder; import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders; import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.sort.SortBuilders; import org.elasticsearch.search.sort.SortOrder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.io.IOException; import java.util.ArrayList; @Service public class HotelService extends ServiceImpl<HotelMapper, Hotel> implements IHotelService { @Autowired private RestHighLevelClient client; @Override public PageResult list(SearchParams searchParams) { try { //获取参数 String key = searchParams.getKey(); Integer page = searchParams.getPage(); Integer size = searchParams.getSize(); String sortBy = searchParams.getSortBy(); SearchRequest searchRequest = new SearchRequest(EsConstant.INDEX_HOTEL); //1.过滤查询、创建boolean查询 BoolQueryBuilder boolQuery = QueryBuilders.boolQuery(); //1.1搜索框使用must if (StringUtils.isBlank(key)){ //关键字为空match_all搜索 boolQuery.must(QueryBuilders.matchAllQuery()); }else { //关键字不为空match搜索 boolQuery.must(QueryBuilders.matchQuery("all", key)); } //1.2品牌过滤 String brand = searchParams.getBrand(); if (StringUtils.isNotBlank(brand)){ boolQuery.filter(QueryBuilders.termQuery("brand", brand)); } //1.3星级过滤 String starName = searchParams.getStarName(); if (StringUtils.isNotBlank(starName)){ boolQuery.filter(QueryBuilders.termQuery("starName", starName)); } //1.4价格过滤 Integer maxPrice = searchParams.getMaxPrice(); Integer minPrice = searchParams.getMinPrice(); if (maxPrice!=null&&minPrice!=null){ boolQuery.filter(QueryBuilders.rangeQuery("price") .gte(minPrice) .lte(maxPrice)); } //1.5城市过滤 String city = searchParams.getCity(); if (StringUtils.isNotBlank(city)){ boolQuery.filter(QueryBuilders.termQuery("city", city)); } //1.6将boolQuery对象添加到query中 searchRequest.source().query(boolQuery); //2.周边酒店(距离排序) // searchRequest.source().sort("_score");//根据分值排序默认降序 String location = searchParams.getLocation(); if (StringUtils.isNotBlank(location)){ searchRequest.source().sort( SortBuilders.geoDistanceSort("location", new GeoPoint(location)) .order(SortOrder.ASC) .unit(DistanceUnit.KILOMETERS) ); } /* searchRequest.source().query(QueryBuilders.functionScoreQuery(boolQuery, new FunctionScoreQueryBuilder.FilterFunctionBuilder[]{ new FunctionScoreQueryBuilder.FilterFunctionBuilder( QueryBuilders.termQuery("isAD", true), ScoreFunctionBuilders.weightFactorFunction(100.0F) ) }).boostMode(CombineFunction.SUM));*/ //3.广告排位 // searchRequest.source().query(new FunctionScoreQueryBuilder(, )) searchRequest.source().query( new FunctionScoreQueryBuilder(boolQuery, new FunctionScoreQueryBuilder.FilterFunctionBuilder[]{ new FunctionScoreQueryBuilder.FilterFunctionBuilder( QueryBuilders.termQuery("isAD", true), ScoreFunctionBuilders.weightFactorFunction(100.0F) ) }).boostMode(CombineFunction.SUM)); //分页 searchRequest.source().from((page-1)*size).size(size); SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT); long total = searchResponse.getHits().getTotalHits().value; //数据封装 SearchHit[] hits = searchResponse.getHits().getHits(); ArrayList<HotelDoc> list = new ArrayList<>(); for (SearchHit hit : hits) { String json = hit.getSourceAsString(); Object[] sortValues = hit.getSortValues(); HotelDoc hotelDoc = JSONObject.parseObject(json, HotelDoc.class); if (sortValues.length>0){ hotelDoc.setDistance(sortValues[0]); } list.add(hotelDoc); } return new PageResult(total, list); } catch (IOException e) { e.printStackTrace(); } return new PageResult(); } }
ElasticSearch搜索常用操作,条件过滤,排序,根据比分排位
最新推荐文章于 2023-07-27 09:04:33 发布