参照
//快速入门
@Test
void testmatchall() throws IOException {
//1.准备request
SearchRequest request = new SearchRequest("hotel");
//2. 准备dsl
request.source().query(QueryBuilders.matchAllQuery());
//3.发送请求
SearchResponse response = client.search(request,RequestOptions.DEFAULT);
//4.解析响应
SearchHits searchHits = response.getHits();
//4.1 获取总条数
long total = searchHits.getTotalHits().value;
System.out.println("共搜索到:"+ total);
//4.2文档数组
SearchHit[] hits = searchHits.getHits();
//4.3遍历
for (SearchHit hit : hits){
//得到json
String json = hit.getSourceAsString();
//转换对象
HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
System.out.println("hotelDoc = " + hotelDoc);
}
System.out.println(response);
}
解析地理坐标的距离
private PageResult handleResponse(SearchResponse response) {
//4.解析响应
SearchHits searchHits = response.getHits();
//4.1获取总条数
long total = searchHits.getTotalHits().value;
//4.2文档数组
SearchHit[] hits = searchHits.getHits();
//4.3遍历
List<HotelDoc> hotels = new ArrayList<>();
for (SearchHit hit : hits){
//获取文档source
String json = hit.getSourceAsString();
//反序列化
HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
//获取排序值
Object[] sortValues = hit.getSortValues();
if (sortValues.length > 0 ){
Object sortValue = sortValues[0];
hotelDoc.setDistance(sortValue);
}
hotels.add(hotelDoc);
}
//4.4封装返回
return new PageResult(total,hotels);
}
##5. 算分控制
//2.算分控制
FunctionScoreQueryBuilder functionScoreQuery =
QueryBuilders.functionScoreQuery(
//原始查询,做相关性算分
boolQueryBuilder,
//function score数组
new FunctionScoreQueryBuilder.FilterFunctionBuilder[]{
//其中一个function score元素
new FunctionScoreQueryBuilder.FilterFunctionBuilder(
//过滤条件
QueryBuilders.termQuery("isAD",true),
//算分函数
ScoreFunctionBuilders.weightFactorFunction(10)
)
});
@Service
public class HotelService implements IHotelService {
@Autowired
public HotelMapper hotelMapper;
@Autowired
private RestHighLevelClient client;
@Override
public List<Hotel> listhotel() {
System.out.println(hotelMapper.listhotel());
return hotelMapper.listhotel();
}
@Override
public Hotel getById(long id) {
return hotelMapper.getById(id);
}
@Override
public PageResult search(RequestParams params) {
try {
//1.准备request
SearchRequest request = new SearchRequest("hotel");
//2.准备dsl
//2.1 query查询
buildBaisc(params, request);
//2.2 分页
int page = params.getPage();
int size = params.getSize();
request.source().from((page - 1) * size).size(size);
//2.3排序
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.发送请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//4.解析响应
return handleResponse(response);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException();
}
}
public Map<String, List<String>> filters(RequestParams params){
try {
//1.准备reuest
SearchRequest request = new SearchRequest("hotel");
//2.准备dsl
//2.1准备query
buildBaisc(params, request);
//2.1 设置size
request.source().size(0);
//2.2聚合
buildAggregation(request);
/* 3.发出 */
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
System.out.println("response = " + response);
//4.解析结果
Map<String,List<String>> result = new HashMap<>();
Aggregations aggregations = response.getAggregations();
//4.1根据品牌获取品牌结果
List<String> brandList = getAggByname(aggregations,"brandAgg");
result.put("品牌",brandList);
//4.2根据品牌获取品牌结果
List<String> cityList = getAggByname(aggregations,"cityAgg");
result.put("城市",cityList);
//4.3根据品牌获取品牌结果
List<String> starList = getAggByname(aggregations,"starNameAgg");
result.put("星级",starList);
return result;
} catch (IOException e) {
throw new RuntimeException();
}
}
private List<String> getAggByname(Aggregations aggregations, String aggName) {
//4.1根据聚合名称获取聚合结果
Terms brandTerms = aggregations.get(aggName);
//4.2获取buckets
List<? extends Terms.Bucket> buckets = brandTerms.getBuckets();
//4.3遍历
List<String> brandList = new ArrayList<>();
for (Terms.Bucket bucket:buckets){
//4.4获取key
String key = bucket.getKeyAsString();
brandList.add(key);
}
return brandList;
}
private void buildAggregation(SearchRequest request) {
request.source().aggregation(AggregationBuilders
.terms("brandAgg")
.field("brand")
.size(100)
);
request.source().aggregation(AggregationBuilders
.terms("cityAgg")
.field("city")
.size(100)
);
request.source().aggregation(AggregationBuilders
.terms("starNameAgg")
.field("starName")
.size(100)
);
}
private void buildBaisc(RequestParams params, SearchRequest request) {
// 1.构建BooleanQuery
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 && !params.getCity().equals("")){
boolQuery.filter(QueryBuilders.termQuery("city", params.getCity()));
}
//品牌条件
if (params.getBrand() !=null && !params.getBrand().equals("")){
boolQuery.filter(QueryBuilders.termQuery("brand", params.getBrand()));
}
//星级条件
if (params.getStarName() !=null && !params.getStarName().equals("")){
System.out.println(params.getStarName());
boolQuery.filter(QueryBuilders.termQuery("starName", params.getStarName()));
}
//价格条件
if ( params.getMinPrice()!=null && params.getMaxPrice()!=null){
boolQuery.filter(QueryBuilders.rangeQuery("price").gte(params.getMinPrice()).lte(params.getMaxPrice()));
}
//2.算分控制
FunctionScoreQueryBuilder functionScoreQuery =
QueryBuilders.functionScoreQuery(
//原始查询,做相关性算分
boolQuery,
//function score数组
new FunctionScoreQueryBuilder.FilterFunctionBuilder[]{
//其中一个function score元素
new FunctionScoreQueryBuilder.FilterFunctionBuilder(
//过滤条件
QueryBuilders.termQuery("aD",true),
//算分函数
ScoreFunctionBuilders.weightFactorFunction(10)
)
});
request.source().query(functionScoreQuery);
}
private PageResult handleResponse(SearchResponse response) {
//4.解析响应
SearchHits searchHits = response.getHits();
//4.1获取总条数
long total = searchHits.getTotalHits().value;
//4.2文档数组
SearchHit[] hits = searchHits.getHits();
//4.3遍历
List<HotelDoc> hotels = new ArrayList<>();
for (SearchHit hit : hits){
//获取文档source
String json = hit.getSourceAsString();
//反序列化
HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
//获取排序值
Object[] sortValues = hit.getSortValues();
if (sortValues.length > 0 ){
Object sortValue = sortValues[0];
hotelDoc.setDistance(sortValue);
}
hotels.add(hotelDoc);
}
//4.4封装返回
return new PageResult(total,hotels);
}
}