调整各种排序器顺序以用户指定的顺序为准

This commit is contained in:
xpc1024 2022-09-17 20:30:51 +08:00
parent 91de8657c9
commit cec6a468fc
9 changed files with 133 additions and 117 deletions

View File

@ -0,0 +1,25 @@
package cn.easyes.common.enums;
/**
* 排序器类型枚举
* <p>
* Copyright © 2022 xpc1024 All Rights Reserved
**/
public enum OrderTypeEnum {
/**
* 常规字段排序器
*/
FIELD,
/**
* 用户自定义的原生语法排序器
*/
CUSTOMIZE,
/**
* 得分排序器
*/
SCORE,
/**
* 地理位置排序器
*/
GEO;
}

View File

@ -1,28 +1,42 @@
package cn.easyes.core.biz;
import cn.easyes.common.enums.OrderTypeEnum;
import lombok.Builder;
import lombok.Data;
import org.elasticsearch.common.geo.GeoDistance;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.unit.DistanceUnit;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortOrder;
/**
* 距离排序参数
* 排序基本参数
* <p>
* Copyright © 2022 xpc1024 All Rights Reserved
**/
@Data
@Builder
public class DistanceOrderByParam {
/**
* 排序字段
*/
private String fieldName;
public class BaseSortParam {
/**
* 排序规则
*/
private SortOrder sortOrder;
/**
* 排序字段
*/
private String sortField;
/**
* 用户自定义的原生语法排序器
*/
private SortBuilder<?> sortBuilder;
/**
* 排序类型
*/
private OrderTypeEnum orderTypeEnum;
/**
* 计算方式 ARC PLANE 默认PLANE
*/

View File

@ -3,7 +3,7 @@ package cn.easyes.core.biz;
import lombok.Data;
/**
* 排序参数
* 自定义排序参数 通常由前端传入
* <p>
* Copyright © 2022 xpc1024 All Rights Reserved
**/

View File

@ -1,24 +0,0 @@
package cn.easyes.core.biz;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.List;
/**
* 排序参数
* <p>
* Copyright © 2021 xpc1024 All Rights Reserved
**/
@Data
@AllArgsConstructor
public class SortParam {
/**
* 是否升序排列
*/
private Boolean isAsc;
/**
* 排序字段
*/
private List<String> fields;
}

View File

@ -22,6 +22,7 @@ import static cn.easyes.common.enums.BaseEsParamTypeEnum.*;
import static cn.easyes.common.enums.EsAttachTypeEnum.*;
import static cn.easyes.common.enums.EsQueryTypeEnum.*;
import static cn.easyes.common.enums.JoinTypeEnum.*;
import static cn.easyes.common.enums.OrderTypeEnum.CUSTOMIZE;
/**
* 抽象Lambda表达式父类
@ -37,10 +38,12 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
* 基础查询参数列表
*/
protected List<BaseEsParam> baseEsParamList;
/**
* 排序查询参数列表
* 基础排序参数列表
*/
protected List<SortParam> sortParamList;
protected List<BaseSortParam> baseSortParams;
/**
* 聚合查询参数列表
*/
@ -53,22 +56,12 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
* geo相关参数
*/
protected GeoParam geoParam;
/**
* 用户自定义的排序规则
*/
protected List<SortBuilder<?>> sortBuilders;
/**
* 得分排序规则
*/
protected SortOrder sortOrder;
/**
* 排序参数列表
*/
protected List<OrderByParam> orderByParams;
/**
* 距离排序参数
*/
protected DistanceOrderByParam distanceOrderByParam;
/**
* 是否查询全部文档
*/
@ -110,7 +103,7 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
*/
protected final void initNeed() {
baseEsParamList = new ArrayList<>();
sortParamList = new ArrayList<>();
baseSortParams = new ArrayList<>();
aggregationParamList = new ArrayList<>();
}
@ -309,8 +302,15 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
}
if (condition) {
List<String> fields = Arrays.asList(columns);
sortParamList.add(new SortParam(isAsc, fields));
Arrays.stream(columns)
.forEach(column -> {
BaseSortParam baseSortParam = BaseSortParam.builder()
.sortField(column)
.sortOrder(isAsc ? SortOrder.ASC : SortOrder.DESC)
.orderTypeEnum(OrderTypeEnum.FIELD)
.build();
baseSortParams.add(baseSortParam);
});
}
return typedThis;
}
@ -327,13 +327,15 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
public Children orderByDistanceAsc(boolean condition, String column, DistanceUnit unit, GeoDistance geoDistance, GeoPoint... geoPoints) {
if (ArrayUtils.isNotEmpty(geoPoints)) {
if (condition) {
this.distanceOrderByParam = DistanceOrderByParam.builder()
.fieldName(column)
BaseSortParam baseSortParam = BaseSortParam.builder()
.sortField(column)
.sortOrder(SortOrder.ASC)
.orderTypeEnum(OrderTypeEnum.GEO)
.geoPoints(geoPoints)
.unit(unit)
.geoDistance(geoDistance)
.sortOrder(SortOrder.ASC)
.build();
baseSortParams.add(baseSortParam);
}
}
return typedThis;
@ -343,13 +345,15 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
public Children orderByDistanceDesc(boolean condition, String column, DistanceUnit unit, GeoDistance geoDistance, GeoPoint... geoPoints) {
if (ArrayUtils.isNotEmpty(geoPoints)) {
if (condition) {
this.distanceOrderByParam = DistanceOrderByParam.builder()
.fieldName(column)
BaseSortParam baseSortParam = BaseSortParam.builder()
.sortField(column)
.sortOrder(SortOrder.DESC)
.orderTypeEnum(OrderTypeEnum.GEO)
.geoPoints(geoPoints)
.unit(unit)
.geoDistance(geoDistance)
.sortOrder(SortOrder.DESC)
.build();
baseSortParams.add(baseSortParam);
}
}
return typedThis;
@ -361,7 +365,14 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
return typedThis;
}
if (condition) {
this.sortBuilders = sortBuilders;
sortBuilders.forEach(sortBuilder -> {
BaseSortParam baseSortParam = BaseSortParam
.builder()
.orderTypeEnum(CUSTOMIZE)
.sortBuilder(sortBuilder)
.build();
baseSortParams.add(baseSortParam);
});
}
return typedThis;
}
@ -369,7 +380,11 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
@Override
public Children sortByScore(boolean condition, SortOrder sortOrder) {
if (condition) {
this.sortOrder = sortOrder;
BaseSortParam baseSortParam = BaseSortParam.builder()
.sortOrder(sortOrder)
.orderTypeEnum(OrderTypeEnum.SCORE)
.build();
baseSortParams.add(baseSortParam);
}
return typedThis;
}

View File

@ -195,7 +195,8 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
}
// searchAfter必须要进行排序不排序无法进行分页
if (CollectionUtils.isEmpty(wrapper.sortParamList)) {
boolean notSort = CollectionUtils.isEmpty(wrapper.baseSortParams) && CollectionUtils.isEmpty(wrapper.orderByParams);
if (notSort) {
throw ExceptionUtils.eee("sortParamList cannot be empty");
}

View File

@ -3,10 +3,7 @@ package cn.easyes.core.conditions;
import cn.easyes.common.params.SFunction;
import cn.easyes.common.utils.ArrayUtils;
import cn.easyes.common.utils.ExceptionUtils;
import cn.easyes.core.biz.AggregationParam;
import cn.easyes.core.biz.BaseEsParam;
import cn.easyes.core.biz.EntityFieldInfo;
import cn.easyes.core.biz.SortParam;
import cn.easyes.core.biz.*;
import cn.easyes.core.conditions.interfaces.Query;
import cn.easyes.core.toolkit.EntityInfoHelper;
import org.elasticsearch.action.search.SearchRequest;
@ -64,19 +61,19 @@ public class LambdaEsQueryWrapper<T> extends AbstractLambdaQueryWrapper<T, Lambd
exclude = new String[]{};
}
LambdaEsQueryWrapper(T entity, List<BaseEsParam> baseEsParamList, List<SortParam> sortParamList,
LambdaEsQueryWrapper(T entity, List<BaseEsParam> baseEsParamList, List<BaseSortParam> baseSortParams,
List<AggregationParam> aggregationParamList) {
super.setEntity(entity);
include = new String[]{};
exclude = new String[]{};
this.baseEsParamList = baseEsParamList;
this.sortParamList = sortParamList;
this.baseSortParams = baseSortParams;
this.aggregationParamList = aggregationParamList;
}
@Override
protected LambdaEsQueryWrapper<T> instance() {
return new LambdaEsQueryWrapper<>(entity, baseEsParamList, sortParamList, aggregationParamList);
return new LambdaEsQueryWrapper<>(entity, baseEsParamList, baseSortParams, aggregationParamList);
}
@Override

View File

@ -21,15 +21,17 @@ import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.collapse.CollapseBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.GeoDistanceSortBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import java.util.*;
import static cn.easyes.common.constants.BaseEsConstants.*;
import static cn.easyes.common.constants.BaseEsConstants.DEFAULT_SIZE;
import static cn.easyes.common.constants.BaseEsConstants.REPEAT_NUM_KEY;
import static cn.easyes.common.enums.BaseEsParamTypeEnum.*;
import static cn.easyes.common.enums.EsAttachTypeEnum.*;
import static org.elasticsearch.index.query.QueryBuilders.geoShapeQuery;
/**
* 核心 wrpeer处理类
@ -311,9 +313,9 @@ public class WrapperProcessor {
// 构造查询参数
GeoShapeQueryBuilder builder;
if (StringUtils.isNotBlank(geoParam.getIndexedShapeId())) {
builder = QueryBuilders.geoShapeQuery(geoParam.getField(), geoParam.getIndexedShapeId());
builder = geoShapeQuery(geoParam.getField(), geoParam.getIndexedShapeId());
} else {
builder = QueryBuilders.geoShapeQuery(geoParam.getField(), geoParam.getGeometry());
builder = geoShapeQuery(geoParam.getField(), geoParam.getGeometry());
}
Optional.ofNullable(geoParam.getShapeRelation()).ifPresent(builder::relation);
@ -549,42 +551,22 @@ public class WrapperProcessor {
// 获取配置
GlobalConfig.DbConfig dbConfig = GlobalConfigCache.getGlobalConfig().getDbConfig();
// 设置排序字段
if (CollectionUtils.isNotEmpty(wrapper.sortParamList)) {
wrapper.sortParamList.forEach(sortParam -> {
SortOrder sortOrder = sortParam.getIsAsc() ? SortOrder.ASC : SortOrder.DESC;
sortParam.getFields().forEach(field -> {
FieldSortBuilder fieldSortBuilder;
String customField = FieldUtils.getRealField(field, mappingColumnMap, dbConfig);
if (Objects.nonNull(customField)) {
fieldSortBuilder = new FieldSortBuilder(customField).order(sortOrder);
} else {
if (dbConfig.isMapUnderscoreToCamelCase()) {
fieldSortBuilder = new FieldSortBuilder(StringUtils.camelToUnderline(field)).order(sortOrder);
} else {
fieldSortBuilder = new FieldSortBuilder(field).order(sortOrder);
}
}
searchSourceBuilder.sort(fieldSortBuilder);
});
// 批量设置排序字段
if (CollectionUtils.isNotEmpty(wrapper.baseSortParams)) {
wrapper.baseSortParams.forEach(baseSortParam -> {
// 获取es中的实际字段 有可能已经被用户自定义或者驼峰转成下划线
String realField = Objects.isNull(baseSortParam.getSortField()) ?
null : FieldUtils.getRealField(baseSortParam.getSortField(), mappingColumnMap, dbConfig);
SortBuilder<?> sortBuilder = getSortBuilder(realField, baseSortParam);
Optional.ofNullable(sortBuilder).ifPresent(searchSourceBuilder::sort);
});
}
// 设置以String形式指定的排序字段及规则
// 设置以String形式指定的自定义排序字段及规则(此类排序通常由前端传入,满足部分用户个性化需求)
if (CollectionUtils.isNotEmpty(wrapper.orderByParams)) {
wrapper.orderByParams.forEach(orderByParam -> {
// 设置排序字段
FieldSortBuilder fieldSortBuilder;
String customField = FieldUtils.getRealField(orderByParam.getOrder(), mappingColumnMap, dbConfig);
if (Objects.nonNull(customField)) {
fieldSortBuilder = new FieldSortBuilder(customField);
} else {
if (dbConfig.isMapUnderscoreToCamelCase()) {
fieldSortBuilder = new FieldSortBuilder(StringUtils.camelToUnderline(orderByParam.getOrder()));
} else {
fieldSortBuilder = new FieldSortBuilder(orderByParam.getOrder());
}
}
FieldSortBuilder fieldSortBuilder = new FieldSortBuilder(orderByParam.getOrder());
// 设置排序规则
if (SortOrder.ASC.toString().equalsIgnoreCase(orderByParam.getSort())) {
@ -596,26 +578,32 @@ public class WrapperProcessor {
searchSourceBuilder.sort(fieldSortBuilder);
});
}
// 设置用户自定义的sorts
if (CollectionUtils.isNotEmpty(wrapper.sortBuilders)) {
wrapper.sortBuilders.forEach(searchSourceBuilder::sort);
}
// 设置得分排序规则
Optional.ofNullable(wrapper.sortOrder)
.ifPresent(sortOrder -> searchSourceBuilder.sort(SCORE_FIELD, sortOrder));
// 设置距离排序
Optional.ofNullable(wrapper.distanceOrderByParam)
.ifPresent(distanceOrderByParam -> {
GeoDistanceSortBuilder geoDistanceSortBuilder =
SortBuilders.geoDistanceSort(distanceOrderByParam.getFieldName(), distanceOrderByParam.getGeoPoints())
.order(distanceOrderByParam.getSortOrder())
.geoDistance(distanceOrderByParam.getGeoDistance())
.unit(distanceOrderByParam.getUnit());
searchSourceBuilder.sort(geoDistanceSortBuilder);
});
/**
* 获取排序器
*
* @param realField 实际字段名称
* @param baseSortParam 排序参数
* @return 排序器
*/
private static SortBuilder<?> getSortBuilder(String realField, BaseSortParam baseSortParam) {
switch (baseSortParam.getOrderTypeEnum()) {
case FIELD:
return SortBuilders.fieldSort(realField).order(baseSortParam.getSortOrder());
case SCORE:
return SortBuilders.scoreSort().order(baseSortParam.getSortOrder());
case GEO:
return SortBuilders.geoDistanceSort(realField, baseSortParam.getGeoPoints())
.order(baseSortParam.getSortOrder())
.geoDistance(baseSortParam.getGeoDistance())
.unit(baseSortParam.getUnit());
case CUSTOMIZE:
return baseSortParam.getSortBuilder();
default:
return null;
}
}

View File

@ -602,7 +602,7 @@ public class AllTest {
wrapper.match(Document::getCreator, "老汉");
List<OrderByParam> orderByParams = new ArrayList<>();
OrderByParam orderByParam = new OrderByParam();
orderByParam.setOrder("starNum");
orderByParam.setOrder("star_num");
orderByParam.setSort("DESC");
orderByParams.add(orderByParam);
wrapper.orderBy(orderByParams);