一、在构建利用 FunctionScoreQueryBuilder改变某字段值的时候,需要 以"_score"排序,但是查出来的_score分数为0.0或null,主要原因是:查询语句searchQuery里面使用了其它字段作为排序字段,es默认使用score为排序字段,如果使用其它字段作为排序字段,_score则为null,但是还需要注意的是,构建查询条件时,有过滤条件的查询语句{QueryBuilders.boolQuery().filter()},_score分数也会为0.0或null;
// 2.改变算分
private FunctionScoreQueryBuilder getFunctionScoreQueryBuilder(BoolQueryBuilder boolQuery, String name) {
return QueryBuilders.functionScoreQuery(
// 原始查询,相关性算分的查询
boolQuery,
// function score的数组
new FunctionScoreQueryBuilder.FilterFunctionBuilder[]{
// 其中的一个function score 元素
new FunctionScoreQueryBuilder.FilterFunctionBuilder(
// 过滤条件
QueryBuilders.termQuery(name, true),
// 算分函数
ScoreFunctionBuilders.weightFactorFunction(10)
)
});
}
二、为了避免_score分数为0.0或null,可以在排序条件增加判断条件 ,在没有其他条件的时候默认以_score排序
//排序
private SortBuilder getSortBuilder(Param params) {
if (!StringUtils.isEmpty(params.getLocation())) {
//按距离排序
String[] locationStr = params.getLocation().split(",");
double lon = Double.valueOf(locationStr[1]); //经度
double lat = Double.valueOf(locationStr[0]); //维度
GeoDistanceSortBuilder geoDistanceSortBuilder = SortBuilders.geoDistanceSort("location", new GeoPoint(lat, lon))
.unit(DistanceUnit.KILOMETERS)
.order(SortOrder.ASC);//排序方式
//返回
return geoDistanceSortBuilder;
}
//按字段名排序
else if (!StringUtils.isEmpty(params.getSortBy())) {
FieldSortBuilder fieldSortBuilder = SortBuilders.fieldSort(params.getSortBy());
return fieldSortBuilder;
}
//默认排序 _score
ScoreSortBuilder scoreSortBuilder = SortBuilders.scoreSort();
return scoreSortBuilder;
}
三、构建查询添加时使用 must 或者should, 如果使用了.filter(),_score分数会为0.0或null
private BoolQueryBuilder getBoolQueryBuilder(Param params) {
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
if (StringUtils.isEmpty(params.getKey())) {
//查询所有
boolQuery.must(QueryBuilders.matchAllQuery());
} else {
//设置全文查询
boolQuery.must(QueryBuilders.multiMatchQuery(params.getKey(), "name", "brand", "city", "address"));
}
//设置城市查询
if (!StringUtils.isEmpty(params.getCity())) {
boolQuery.must(QueryBuilders.termQuery("city", params.getCity()));//城市
}
//设置/品牌查询
if (!StringUtils.isEmpty(params.getBrand())) {
boolQuery.must(QueryBuilders.termQuery("brand", params.getBrand()));//品牌
}
//设置星级查询
if (!StringUtils.isEmpty(params.getStarName())) {
boolQuery.must(QueryBuilders.termQuery("starName", params.getStarName()));//星级
}
//设置价格 范围查询
if (!StringUtils.isEmpty(params.getMinPrice()) && !StringUtils.isEmpty(params.getMaxPrice())) {
boolQuery.must(
QueryBuilders.rangeQuery("price").gte(params.getMinPrice()).lte(params.getMaxPrice()));//价格
}
//设置距离查询;根据经纬度查询 location 经纬度字段,distance 距离中心范围KM,lat lon 圆心经纬度
if (!StringUtils.isEmpty(params.getDistance())) {
//距离
double lon = 113.90449; //经度
double lat = 22.57809; //维度
GeoDistanceQueryBuilder locationBuilder = QueryBuilders.geoDistanceQuery("location")//字段名
.distance(Double.valueOf(params.getDistance()), DistanceUnit.KILOMETERS)//半径
.point(new GeoPoint(lat, lon));//经纬度坐标
//添加到查询构建
boolQuery.must(locationBuilder);
}
return boolQuery;
}