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

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

View File

@ -3,7 +3,7 @@ package cn.easyes.core.biz;
import lombok.Data; import lombok.Data;
/** /**
* 排序参数 * 自定义排序参数 通常由前端传入
* <p> * <p>
* Copyright © 2022 xpc1024 All Rights Reserved * 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.EsAttachTypeEnum.*;
import static cn.easyes.common.enums.EsQueryTypeEnum.*; import static cn.easyes.common.enums.EsQueryTypeEnum.*;
import static cn.easyes.common.enums.JoinTypeEnum.*; import static cn.easyes.common.enums.JoinTypeEnum.*;
import static cn.easyes.common.enums.OrderTypeEnum.CUSTOMIZE;
/** /**
* 抽象Lambda表达式父类 * 抽象Lambda表达式父类
@ -37,10 +38,12 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
* 基础查询参数列表 * 基础查询参数列表
*/ */
protected List<BaseEsParam> baseEsParamList; 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相关参数 * geo相关参数
*/ */
protected GeoParam geoParam; protected GeoParam geoParam;
/**
* 用户自定义的排序规则
*/
protected List<SortBuilder<?>> sortBuilders;
/**
* 得分排序规则
*/
protected SortOrder sortOrder;
/** /**
* 排序参数列表 * 排序参数列表
*/ */
protected List<OrderByParam> orderByParams; 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() { protected final void initNeed() {
baseEsParamList = new ArrayList<>(); baseEsParamList = new ArrayList<>();
sortParamList = new ArrayList<>(); baseSortParams = new ArrayList<>();
aggregationParamList = new ArrayList<>(); aggregationParamList = new ArrayList<>();
} }
@ -309,8 +302,15 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
} }
if (condition) { if (condition) {
List<String> fields = Arrays.asList(columns); Arrays.stream(columns)
sortParamList.add(new SortParam(isAsc, fields)); .forEach(column -> {
BaseSortParam baseSortParam = BaseSortParam.builder()
.sortField(column)
.sortOrder(isAsc ? SortOrder.ASC : SortOrder.DESC)
.orderTypeEnum(OrderTypeEnum.FIELD)
.build();
baseSortParams.add(baseSortParam);
});
} }
return typedThis; 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) { public Children orderByDistanceAsc(boolean condition, String column, DistanceUnit unit, GeoDistance geoDistance, GeoPoint... geoPoints) {
if (ArrayUtils.isNotEmpty(geoPoints)) { if (ArrayUtils.isNotEmpty(geoPoints)) {
if (condition) { if (condition) {
this.distanceOrderByParam = DistanceOrderByParam.builder() BaseSortParam baseSortParam = BaseSortParam.builder()
.fieldName(column) .sortField(column)
.sortOrder(SortOrder.ASC)
.orderTypeEnum(OrderTypeEnum.GEO)
.geoPoints(geoPoints) .geoPoints(geoPoints)
.unit(unit) .unit(unit)
.geoDistance(geoDistance) .geoDistance(geoDistance)
.sortOrder(SortOrder.ASC)
.build(); .build();
baseSortParams.add(baseSortParam);
} }
} }
return typedThis; 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) { public Children orderByDistanceDesc(boolean condition, String column, DistanceUnit unit, GeoDistance geoDistance, GeoPoint... geoPoints) {
if (ArrayUtils.isNotEmpty(geoPoints)) { if (ArrayUtils.isNotEmpty(geoPoints)) {
if (condition) { if (condition) {
this.distanceOrderByParam = DistanceOrderByParam.builder() BaseSortParam baseSortParam = BaseSortParam.builder()
.fieldName(column) .sortField(column)
.sortOrder(SortOrder.DESC)
.orderTypeEnum(OrderTypeEnum.GEO)
.geoPoints(geoPoints) .geoPoints(geoPoints)
.unit(unit) .unit(unit)
.geoDistance(geoDistance) .geoDistance(geoDistance)
.sortOrder(SortOrder.DESC)
.build(); .build();
baseSortParams.add(baseSortParam);
} }
} }
return typedThis; return typedThis;
@ -361,7 +365,14 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
return typedThis; return typedThis;
} }
if (condition) { if (condition) {
this.sortBuilders = sortBuilders; sortBuilders.forEach(sortBuilder -> {
BaseSortParam baseSortParam = BaseSortParam
.builder()
.orderTypeEnum(CUSTOMIZE)
.sortBuilder(sortBuilder)
.build();
baseSortParams.add(baseSortParam);
});
} }
return typedThis; return typedThis;
} }
@ -369,7 +380,11 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
@Override @Override
public Children sortByScore(boolean condition, SortOrder sortOrder) { public Children sortByScore(boolean condition, SortOrder sortOrder) {
if (condition) { if (condition) {
this.sortOrder = sortOrder; BaseSortParam baseSortParam = BaseSortParam.builder()
.sortOrder(sortOrder)
.orderTypeEnum(OrderTypeEnum.SCORE)
.build();
baseSortParams.add(baseSortParam);
} }
return typedThis; return typedThis;
} }

View File

@ -195,7 +195,8 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
} }
// searchAfter必须要进行排序不排序无法进行分页 // 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"); 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.params.SFunction;
import cn.easyes.common.utils.ArrayUtils; import cn.easyes.common.utils.ArrayUtils;
import cn.easyes.common.utils.ExceptionUtils; import cn.easyes.common.utils.ExceptionUtils;
import cn.easyes.core.biz.AggregationParam; import cn.easyes.core.biz.*;
import cn.easyes.core.biz.BaseEsParam;
import cn.easyes.core.biz.EntityFieldInfo;
import cn.easyes.core.biz.SortParam;
import cn.easyes.core.conditions.interfaces.Query; import cn.easyes.core.conditions.interfaces.Query;
import cn.easyes.core.toolkit.EntityInfoHelper; import cn.easyes.core.toolkit.EntityInfoHelper;
import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchRequest;
@ -64,19 +61,19 @@ public class LambdaEsQueryWrapper<T> extends AbstractLambdaQueryWrapper<T, Lambd
exclude = new String[]{}; exclude = new String[]{};
} }
LambdaEsQueryWrapper(T entity, List<BaseEsParam> baseEsParamList, List<SortParam> sortParamList, LambdaEsQueryWrapper(T entity, List<BaseEsParam> baseEsParamList, List<BaseSortParam> baseSortParams,
List<AggregationParam> aggregationParamList) { List<AggregationParam> aggregationParamList) {
super.setEntity(entity); super.setEntity(entity);
include = new String[]{}; include = new String[]{};
exclude = new String[]{}; exclude = new String[]{};
this.baseEsParamList = baseEsParamList; this.baseEsParamList = baseEsParamList;
this.sortParamList = sortParamList; this.baseSortParams = baseSortParams;
this.aggregationParamList = aggregationParamList; this.aggregationParamList = aggregationParamList;
} }
@Override @Override
protected LambdaEsQueryWrapper<T> instance() { protected LambdaEsQueryWrapper<T> instance() {
return new LambdaEsQueryWrapper<>(entity, baseEsParamList, sortParamList, aggregationParamList); return new LambdaEsQueryWrapper<>(entity, baseEsParamList, baseSortParams, aggregationParamList);
} }
@Override @Override

View File

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

View File

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