mirror of
https://gitee.com/dromara/easy-es.git
synced 2025-12-06 17:18:57 +08:00
调整各种排序器顺序以用户指定的顺序为准
This commit is contained in:
parent
91de8657c9
commit
cec6a468fc
@ -0,0 +1,25 @@
|
||||
package cn.easyes.common.enums;
|
||||
|
||||
/**
|
||||
* 排序器类型枚举
|
||||
* <p>
|
||||
* Copyright © 2022 xpc1024 All Rights Reserved
|
||||
**/
|
||||
public enum OrderTypeEnum {
|
||||
/**
|
||||
* 常规字段排序器
|
||||
*/
|
||||
FIELD,
|
||||
/**
|
||||
* 用户自定义的原生语法排序器
|
||||
*/
|
||||
CUSTOMIZE,
|
||||
/**
|
||||
* 得分排序器
|
||||
*/
|
||||
SCORE,
|
||||
/**
|
||||
* 地理位置排序器
|
||||
*/
|
||||
GEO;
|
||||
}
|
||||
@ -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
|
||||
*/
|
||||
@ -3,7 +3,7 @@ package cn.easyes.core.biz;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 排序参数
|
||||
* 自定义排序参数 通常由前端传入
|
||||
* <p>
|
||||
* Copyright © 2022 xpc1024 All Rights Reserved
|
||||
**/
|
||||
|
||||
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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");
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
/**
|
||||
* 获取排序器
|
||||
*
|
||||
* @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);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user