feat: 当用户id列不存在source中时, 使用_id进行查询/排序/聚合, 此时需要开启集群配置indices.id_field_data.enabled

This commit is contained in:
jaime 2025-02-27 15:42:54 +08:00
parent aa7c1cf4a6
commit 2feafdef30
6 changed files with 136 additions and 114 deletions

View File

@ -97,31 +97,31 @@ public class WrapperProcessor {
setBool(bool, param.getQueryBuilder().build(), param.getPrevQueryType()); setBool(bool, param.getQueryBuilder().build(), param.getPrevQueryType());
break; break;
case TERM: case TERM:
realField = getRealFieldAndSuffix(param.getColumn(), fieldTypeMap, mappingColumnMap); realField = getRealFieldAndSuffix(param.getColumn(), fieldTypeMap, mappingColumnMap, entityInfo);
query = Query.of(q -> q.term(p -> query = Query.of(q -> q.term(p ->
p.field(realField).value(fieldValue(param.getVal())).boost(param.getBoost()))); p.field(realField).value(fieldValue(param.getVal())).boost(param.getBoost())));
setBool(bool, query, param.getPrevQueryType()); setBool(bool, query, param.getPrevQueryType());
break; break;
case MATCH: case MATCH:
realField = getRealField(param.getColumn(), mappingColumnMap); realField = getRealField(param.getColumn(), mappingColumnMap, entityInfo);
query = Query.of(q -> q.match(p -> query = Query.of(q -> q.match(p ->
p.field(realField).query(fieldValue(param.getVal())).boost(param.getBoost()))); p.field(realField).query(fieldValue(param.getVal())).boost(param.getBoost())));
setBool(bool, query, param.getPrevQueryType()); setBool(bool, query, param.getPrevQueryType());
break; break;
case MATCH_PHRASE: case MATCH_PHRASE:
realField = getRealField(param.getColumn(), mappingColumnMap); realField = getRealField(param.getColumn(), mappingColumnMap, entityInfo);
query = Query.of(q -> q.matchPhrase(p -> query = Query.of(q -> q.matchPhrase(p ->
p.field(realField).query((String) param.getVal()).boost(param.getBoost()))); p.field(realField).query((String) param.getVal()).boost(param.getBoost())));
setBool(bool, query, param.getPrevQueryType()); setBool(bool, query, param.getPrevQueryType());
break; break;
case MATCH_PHRASE_PREFIX: case MATCH_PHRASE_PREFIX:
realField = getRealField(param.getColumn(), mappingColumnMap); realField = getRealField(param.getColumn(), mappingColumnMap, entityInfo);
query = Query.of(q -> q.matchPhrasePrefix(p -> query = Query.of(q -> q.matchPhrasePrefix(p ->
p.field(realField).query((String) param.getVal()).boost(param.getBoost()).maxExpansions((int) param.getExt1()))); p.field(realField).query((String) param.getVal()).boost(param.getBoost()).maxExpansions((int) param.getExt1())));
setBool(bool, query, param.getPrevQueryType()); setBool(bool, query, param.getPrevQueryType());
break; break;
case MULTI_MATCH: case MULTI_MATCH:
List<String> realFields = getRealFields(param.getColumns(), mappingColumnMap); List<String> realFields = getRealFields(param.getColumns(), mappingColumnMap, entityInfo);
query = Query.of(q -> q.multiMatch(p -> p.query((String) param.getVal()).fields(realFields) query = Query.of(q -> q.multiMatch(p -> p.query((String) param.getVal()).fields(realFields)
.operator((Operator) param.getExt1()).minimumShouldMatch(param.getExt2() + PERCENT_SIGN))); .operator((Operator) param.getExt1()).minimumShouldMatch(param.getExt2() + PERCENT_SIGN)));
setBool(bool, query, param.getPrevQueryType()); setBool(bool, query, param.getPrevQueryType());
@ -135,12 +135,12 @@ public class WrapperProcessor {
setBool(bool, query, param.getPrevQueryType()); setBool(bool, query, param.getPrevQueryType());
break; break;
case PREFIX: case PREFIX:
realField = getRealField(param.getColumn(), mappingColumnMap); realField = getRealField(param.getColumn(), mappingColumnMap, entityInfo);
query = Query.of(q -> q.prefix(p -> p.field(realField).value((String) param.getVal()).boost(param.getBoost()))); query = Query.of(q -> q.prefix(p -> p.field(realField).value((String) param.getVal()).boost(param.getBoost())));
setBool(bool, query, param.getPrevQueryType()); setBool(bool, query, param.getPrevQueryType());
break; break;
case GT: case GT:
realField = getRealFieldAndSuffix(param.getColumn(), fieldTypeMap, mappingColumnMap); realField = getRealFieldAndSuffix(param.getColumn(), fieldTypeMap, mappingColumnMap, entityInfo);
query = Query.of(q -> q.range(p -> query = Query.of(q -> q.range(p ->
p.untyped(v -> { p.untyped(v -> {
v.field(realField).gt(JsonData.of(param.getVal())).boost(param.getBoost()); v.field(realField).gt(JsonData.of(param.getVal())).boost(param.getBoost());
@ -152,7 +152,7 @@ public class WrapperProcessor {
setBool(bool, query, param.getPrevQueryType()); setBool(bool, query, param.getPrevQueryType());
break; break;
case GE: case GE:
realField = getRealFieldAndSuffix(param.getColumn(), fieldTypeMap, mappingColumnMap); realField = getRealFieldAndSuffix(param.getColumn(), fieldTypeMap, mappingColumnMap, entityInfo);
query = Query.of(q -> q.range(p -> query = Query.of(q -> q.range(p ->
p.untyped(v -> { p.untyped(v -> {
v.field(realField).gte(JsonData.of(param.getVal())).boost(param.getBoost()); v.field(realField).gte(JsonData.of(param.getVal())).boost(param.getBoost());
@ -164,7 +164,7 @@ public class WrapperProcessor {
setBool(bool, query, param.getPrevQueryType()); setBool(bool, query, param.getPrevQueryType());
break; break;
case LT: case LT:
realField = getRealFieldAndSuffix(param.getColumn(), fieldTypeMap, mappingColumnMap); realField = getRealFieldAndSuffix(param.getColumn(), fieldTypeMap, mappingColumnMap, entityInfo);
query = Query.of(q -> q.range(p -> query = Query.of(q -> q.range(p ->
p.untyped(v -> { p.untyped(v -> {
v.field(realField).lt(JsonData.of(param.getVal())).boost(param.getBoost()); v.field(realField).lt(JsonData.of(param.getVal())).boost(param.getBoost());
@ -176,7 +176,7 @@ public class WrapperProcessor {
setBool(bool, query, param.getPrevQueryType()); setBool(bool, query, param.getPrevQueryType());
break; break;
case LE: case LE:
realField = getRealFieldAndSuffix(param.getColumn(), fieldTypeMap, mappingColumnMap); realField = getRealFieldAndSuffix(param.getColumn(), fieldTypeMap, mappingColumnMap, entityInfo);
query = Query.of(q -> q.range(p -> query = Query.of(q -> q.range(p ->
p.untyped(v -> { p.untyped(v -> {
v.field(realField).lte(JsonData.of(param.getVal())).boost(param.getBoost()); v.field(realField).lte(JsonData.of(param.getVal())).boost(param.getBoost());
@ -188,7 +188,7 @@ public class WrapperProcessor {
setBool(bool, query, param.getPrevQueryType()); setBool(bool, query, param.getPrevQueryType());
break; break;
case BETWEEN: case BETWEEN:
realField = getRealFieldAndSuffix(param.getColumn(), fieldTypeMap, mappingColumnMap); realField = getRealFieldAndSuffix(param.getColumn(), fieldTypeMap, mappingColumnMap, entityInfo);
query = Query.of(q -> q.range(p -> query = Query.of(q -> q.range(p ->
p.untyped(v -> { p.untyped(v -> {
v.field(realField).gte(JsonData.of(param.getExt1())).lte(JsonData.of(param.getExt2())).boost(param.getBoost()); v.field(realField).gte(JsonData.of(param.getExt1())).lte(JsonData.of(param.getExt2())).boost(param.getBoost());
@ -200,24 +200,24 @@ public class WrapperProcessor {
setBool(bool, query, param.getPrevQueryType()); setBool(bool, query, param.getPrevQueryType());
break; break;
case WILDCARD: case WILDCARD:
realField = getRealFieldAndSuffix(param.getColumn(), fieldTypeMap, mappingColumnMap); realField = getRealFieldAndSuffix(param.getColumn(), fieldTypeMap, mappingColumnMap, entityInfo);
query = Query.of(q -> q.wildcard(p -> p.field(realField).value((String) param.getVal()).boost(param.getBoost()))); query = Query.of(q -> q.wildcard(p -> p.field(realField).value((String) param.getVal()).boost(param.getBoost())));
setBool(bool, query, param.getPrevQueryType()); setBool(bool, query, param.getPrevQueryType());
break; break;
case TERMS: case TERMS:
realField = getRealFieldAndSuffix(param.getColumn(), fieldTypeMap, mappingColumnMap); realField = getRealFieldAndSuffix(param.getColumn(), fieldTypeMap, mappingColumnMap, entityInfo);
List<FieldValue> fieldValueList = ((Collection<?>) param.getVal()).stream() List<FieldValue> fieldValueList = ((Collection<?>) param.getVal()).stream()
.map(WrapperProcessor::fieldValue).collect(Collectors.toList()); .map(WrapperProcessor::fieldValue).collect(Collectors.toList());
query = Query.of(q -> q.terms(p -> p.field(realField).terms(t -> t.value(fieldValueList)))); query = Query.of(q -> q.terms(p -> p.field(realField).terms(t -> t.value(fieldValueList))));
setBool(bool, query, param.getPrevQueryType()); setBool(bool, query, param.getPrevQueryType());
break; break;
case EXISTS: case EXISTS:
realField = getRealField(param.getColumn(), mappingColumnMap); realField = getRealField(param.getColumn(), mappingColumnMap, entityInfo);
query = Query.of(q -> q.exists(p -> p.field(realField).boost(param.getBoost()))); query = Query.of(q -> q.exists(p -> p.field(realField).boost(param.getBoost())));
setBool(bool, query, param.getPrevQueryType()); setBool(bool, query, param.getPrevQueryType());
break; break;
case GEO_BOUNDING_BOX: case GEO_BOUNDING_BOX:
realField = getRealField(param.getColumn(), mappingColumnMap); realField = getRealField(param.getColumn(), mappingColumnMap, entityInfo);
query = Query.of(q -> q.geoBoundingBox(p -> p.field(realField) query = Query.of(q -> q.geoBoundingBox(p -> p.field(realField)
.boundingBox(x -> x.tlbr(y -> y .boundingBox(x -> x.tlbr(y -> y
.topLeft((GeoLocation) param.getExt1()) .topLeft((GeoLocation) param.getExt1())
@ -227,7 +227,7 @@ public class WrapperProcessor {
setBool(bool, query, param.getPrevQueryType()); setBool(bool, query, param.getPrevQueryType());
break; break;
case GEO_DISTANCE: case GEO_DISTANCE:
realField = getRealField(param.getColumn(), mappingColumnMap); realField = getRealField(param.getColumn(), mappingColumnMap, entityInfo);
query = Query.of(q -> q.geoDistance(p -> { query = Query.of(q -> q.geoDistance(p -> {
String unit = param.getExt1() == null ? DistanceUnit.Kilometers.jsonValue() : ((DistanceUnit) param.getExt1()).jsonValue(); String unit = param.getExt1() == null ? DistanceUnit.Kilometers.jsonValue() : ((DistanceUnit) param.getExt1()).jsonValue();
Double distance = (Double) param.getVal(); Double distance = (Double) param.getVal();
@ -242,19 +242,19 @@ public class WrapperProcessor {
setBool(bool, query, param.getPrevQueryType()); setBool(bool, query, param.getPrevQueryType());
break; break;
case GEO_POLYGON: case GEO_POLYGON:
realField = getRealField(param.getColumn(), mappingColumnMap); realField = getRealField(param.getColumn(), mappingColumnMap, entityInfo);
query = Query.of(q -> q.geoPolygon(p -> p.field(realField).polygon(x -> query = Query.of(q -> q.geoPolygon(p -> p.field(realField).polygon(x ->
x.points((List<GeoLocation>) param.getVal())))); x.points((List<GeoLocation>) param.getVal()))));
setBool(bool, query, param.getPrevQueryType()); setBool(bool, query, param.getPrevQueryType());
break; break;
case GEO_SHAPE_ID: case GEO_SHAPE_ID:
realField = getRealField(param.getColumn(), mappingColumnMap); realField = getRealField(param.getColumn(), mappingColumnMap, entityInfo);
query = Query.of(q -> q.geoShape(p -> p.field(realField).shape(x -> query = Query.of(q -> q.geoShape(p -> p.field(realField).shape(x ->
x.indexedShape(y -> y.id((String) param.getVal()))))); x.indexedShape(y -> y.id((String) param.getVal())))));
setBool(bool, query, param.getPrevQueryType()); setBool(bool, query, param.getPrevQueryType());
break; break;
case GEO_SHAPE: case GEO_SHAPE:
realField = getRealField(param.getColumn(), mappingColumnMap); realField = getRealField(param.getColumn(), mappingColumnMap, entityInfo);
query = QueryBuilders.geoShape() query = QueryBuilders.geoShape()
.field(realField) .field(realField)
.shape(x -> x .shape(x -> x
@ -267,7 +267,7 @@ public class WrapperProcessor {
setBool(bool, query, param.getPrevQueryType()); setBool(bool, query, param.getPrevQueryType());
break; break;
case PARENT_ID: case PARENT_ID:
realField = getRealField(param.getColumn(), mappingColumnMap); realField = getRealField(param.getColumn(), mappingColumnMap, entityInfo);
query = Query.of(q -> q.parentId(p -> p.type(realField).id((String) param.getVal()))); query = Query.of(q -> q.parentId(p -> p.type(realField).id((String) param.getVal())));
setBool(bool, query, param.getPrevQueryType()); setBool(bool, query, param.getPrevQueryType());
break; break;
@ -280,7 +280,7 @@ public class WrapperProcessor {
setBool(bool, query, param.getPrevQueryType()); setBool(bool, query, param.getPrevQueryType());
break; break;
case NESTED: case NESTED:
realField = getRealField(param.getColumn(), mappingColumnMap); realField = getRealField(param.getColumn(), mappingColumnMap, entityInfo);
String[] split = param.getColumn().split(SIGN); String[] split = param.getColumn().split(SIGN);
String path = split[split.length - 1]; String path = split[split.length - 1];
query = Query.of(b -> b.bool(x -> getBool(children, x, entityInfo, path))); query = Query.of(b -> b.bool(x -> getBool(children, x, entityInfo, path)));
@ -293,7 +293,7 @@ public class WrapperProcessor {
case HAS_PARENT: case HAS_PARENT:
// 如果用户没指定type框架可根据entityInfo上下文自行推断出其父type // 如果用户没指定type框架可根据entityInfo上下文自行推断出其父type
String column = Optional.ofNullable(param.getColumn()).orElse(entityInfo.getParentJoinAlias()); String column = Optional.ofNullable(param.getColumn()).orElse(entityInfo.getParentJoinAlias());
realField = getRealField(column, mappingColumnMap); realField = getRealField(column, mappingColumnMap, entityInfo);
query = Query.of(t -> t.bool(b -> getBool(children, b, entityInfo, param.getColumn()))); query = Query.of(t -> t.bool(b -> getBool(children, b, entityInfo, param.getColumn())));
HasParentQuery.Builder hasParentQueryBuilder = new HasParentQuery.Builder() HasParentQuery.Builder hasParentQueryBuilder = new HasParentQuery.Builder()
.ignoreUnmapped(false) .ignoreUnmapped(false)
@ -303,7 +303,7 @@ public class WrapperProcessor {
setBool(bool, Query.of(x -> x.hasParent(hasParentQueryBuilder.build())), param.getPrevQueryType()); setBool(bool, Query.of(x -> x.hasParent(hasParentQueryBuilder.build())), param.getPrevQueryType());
break; break;
case HAS_CHILD: case HAS_CHILD:
realField = getRealField(param.getColumn(), mappingColumnMap); realField = getRealField(param.getColumn(), mappingColumnMap, entityInfo);
query = Query.of(t -> t.bool(b -> getBool(children, b, entityInfo, param.getColumn()))); query = Query.of(t -> t.bool(b -> getBool(children, b, entityInfo, param.getColumn())));
HasChildQuery.Builder hasChildQueryBuilder = new HasChildQuery.Builder() HasChildQuery.Builder hasChildQueryBuilder = new HasChildQuery.Builder()
.minChildren(1) .minChildren(1)
@ -436,10 +436,10 @@ public class WrapperProcessor {
setHighLight(entityInfo.getHighlightParams(), builder); setHighLight(entityInfo.getHighlightParams(), builder);
// 设置用户指定的各种排序规则 // 设置用户指定的各种排序规则
setSort(wrapper, mappingColumnMap, builder); setSort(wrapper, mappingColumnMap, entityInfo, builder);
// 设置查询或不查询字段 // 设置查询或不查询字段
setFetchSource(wrapper, mappingColumnMap, builder); setFetchSource(wrapper, mappingColumnMap, entityInfo, builder);
// 设置排除_score 小于 min_score 中指定的最小值的文档 // 设置排除_score 小于 min_score 中指定的最小值的文档
Optional.ofNullable(wrapper.minScore).ifPresent(builder::minScore); Optional.ofNullable(wrapper.minScore).ifPresent(builder::minScore);
@ -448,7 +448,7 @@ public class WrapperProcessor {
Optional.ofNullable(wrapper.trackScores).ifPresent(builder::trackScores); Optional.ofNullable(wrapper.trackScores).ifPresent(builder::trackScores);
// 设置聚合参数 // 设置聚合参数
setAggregations(wrapper, mappingColumnMap, builder); setAggregations(wrapper, mappingColumnMap, entityInfo, builder);
// 设置查询起止参数 // 设置查询起止参数
Optional.ofNullable(wrapper.from).ifPresent(builder::from); Optional.ofNullable(wrapper.from).ifPresent(builder::from);
@ -537,17 +537,18 @@ public class WrapperProcessor {
* *
* @param wrapper 参数包装类 * @param wrapper 参数包装类
* @param mappingColumnMap 字段映射map * @param mappingColumnMap 字段映射map
* @param searchSourceBuilder 查询参数建造者 * @param entityInfo 索引信息
* @param searchBuilder 查询参数建造者
*/ */
private static void setFetchSource(Wrapper<?> wrapper, Map<String, String> mappingColumnMap, SearchRequest.Builder searchSourceBuilder) { private static void setFetchSource(Wrapper<?> wrapper, Map<String, String> mappingColumnMap, EntityInfo entityInfo, SearchRequest.Builder searchBuilder) {
if (ArrayUtils.isEmpty(wrapper.include) && ArrayUtils.isEmpty(wrapper.exclude)) { if (ArrayUtils.isEmpty(wrapper.include) && ArrayUtils.isEmpty(wrapper.exclude)) {
return; return;
} }
// 获取实际字段 // 获取实际字段
List<String> includes = FieldUtils.getRealFields(wrapper.include, mappingColumnMap); List<String> includes = FieldUtils.getRealFields(wrapper.include, mappingColumnMap, entityInfo);
List<String> excludes = FieldUtils.getRealFields(wrapper.exclude, mappingColumnMap); List<String> excludes = FieldUtils.getRealFields(wrapper.exclude, mappingColumnMap, entityInfo);
searchSourceBuilder.source(x -> x.filter(y -> y.includes(includes).excludes(excludes))); searchBuilder.source(x -> x.filter(y -> y.includes(includes).excludes(excludes)));
} }
@ -555,16 +556,16 @@ public class WrapperProcessor {
* 设置高亮参数 * 设置高亮参数
* *
* @param highLightParams 高亮参数列表 * @param highLightParams 高亮参数列表
* @param searchSourceBuilder 查询参数建造者 * @param searchBuilder 查询参数建造者
*/ */
private static void setHighLight(List<HighLightParam> highLightParams, SearchRequest.Builder searchSourceBuilder) { private static void setHighLight(List<HighLightParam> highLightParams, SearchRequest.Builder searchBuilder) {
if (CollectionUtils.isEmpty(highLightParams)) { if (CollectionUtils.isEmpty(highLightParams)) {
return; return;
} }
// 初始化高亮参数 // 初始化高亮参数
Highlight.Builder highlightBuilder = initHighlightBuilder(highLightParams, null); Highlight.Builder highlightBuilder = initHighlightBuilder(highLightParams, null);
Optional.ofNullable(highlightBuilder).map(Highlight.Builder::build).ifPresent(searchSourceBuilder::highlight); Optional.ofNullable(highlightBuilder).map(Highlight.Builder::build).ifPresent(searchBuilder::highlight);
} }
private static Highlight.Builder initHighlightBuilder(List<HighLightParam> highLightParams, String path) { private static Highlight.Builder initHighlightBuilder(List<HighLightParam> highLightParams, String path) {
@ -598,17 +599,18 @@ public class WrapperProcessor {
* *
* @param wrapper 参数包装类 * @param wrapper 参数包装类
* @param mappingColumnMap 字段映射map * @param mappingColumnMap 字段映射map
* @param searchSourceBuilder 查询参数建造者 * @param entityInfo 索引信息
* @param searchBuilder 查询参数建造者
*/ */
private static void setSort(Wrapper<?> wrapper, Map<String, String> mappingColumnMap, SearchRequest.Builder searchSourceBuilder) { private static void setSort(Wrapper<?> wrapper, Map<String, String> mappingColumnMap, EntityInfo entityInfo, SearchRequest.Builder searchBuilder) {
// 批量设置排序字段 // 批量设置排序字段
if (CollectionUtils.isNotEmpty(wrapper.baseSortParams)) { if (CollectionUtils.isNotEmpty(wrapper.baseSortParams)) {
wrapper.baseSortParams.forEach(baseSortParam -> { wrapper.baseSortParams.forEach(baseSortParam -> {
// 获取es中的实际字段 有可能已经被用户自定义或者驼峰转成下划线 // 获取es中的实际字段 有可能已经被用户自定义或者驼峰转成下划线
String realField = Objects.isNull(baseSortParam.getSortField()) ? String realField = Objects.isNull(baseSortParam.getSortField()) ?
null : getRealField(baseSortParam.getSortField(), mappingColumnMap); null : getRealField(baseSortParam.getSortField(), mappingColumnMap, entityInfo);
SortOptions sortBuilder = getSortBuilder(realField, baseSortParam); SortOptions sortBuilder = getSortBuilder(realField, baseSortParam);
Optional.ofNullable(sortBuilder).ifPresent(searchSourceBuilder::sort); Optional.ofNullable(sortBuilder).ifPresent(searchBuilder::sort);
}); });
} }
@ -625,7 +627,7 @@ public class WrapperProcessor {
if (SortOrder.Desc.toString().equalsIgnoreCase(orderByParam.getSort())) { if (SortOrder.Desc.toString().equalsIgnoreCase(orderByParam.getSort())) {
fieldSortBuilder.order(SortOrder.Desc); fieldSortBuilder.order(SortOrder.Desc);
} }
searchSourceBuilder.sort(x -> x.field(fieldSortBuilder.build())); searchBuilder.sort(x -> x.field(fieldSortBuilder.build()));
}); });
} }
} }
@ -639,24 +641,18 @@ public class WrapperProcessor {
* @return 排序器 * @return 排序器
*/ */
private static SortOptions getSortBuilder(String realField, BaseSortParam baseSortParam) { private static SortOptions getSortBuilder(String realField, BaseSortParam baseSortParam) {
switch (baseSortParam.getOrderTypeEnum()) { return switch (baseSortParam.getOrderTypeEnum()) {
case FIELD: case FIELD -> SortOptions.of(x -> x.field(y -> y.field(realField).order(baseSortParam.getSortOrder())));
return SortOptions.of(x -> x.field(y -> y.field(realField).order(baseSortParam.getSortOrder()))); case SCORE -> SortOptions.of(x -> x.score(y -> y.order(baseSortParam.getSortOrder())));
case SCORE: case GEO -> SortOptions.of(x -> x.geoDistance(y -> y
return SortOptions.of(x -> x.score(y -> y.order(baseSortParam.getSortOrder())));
case GEO:
return SortOptions.of(x -> x.geoDistance(y -> y
.field(realField) .field(realField)
.location(baseSortParam.getGeoPoints()) .location(baseSortParam.getGeoPoints())
.order(baseSortParam.getSortOrder()) .order(baseSortParam.getSortOrder())
.distanceType(baseSortParam.getGeoDistanceType()) .distanceType(baseSortParam.getGeoDistanceType())
.unit(baseSortParam.getUnit()) .unit(baseSortParam.getUnit())
)); ));
case CUSTOMIZE: case CUSTOMIZE -> baseSortParam.getSortBuilder();
return baseSortParam.getSortBuilder(); };
default:
return null;
}
} }
@ -665,14 +661,15 @@ public class WrapperProcessor {
* *
* @param wrapper 参数包装类 * @param wrapper 参数包装类
* @param mappingColumnMap 字段映射map * @param mappingColumnMap 字段映射map
* @param entityInfo 索引信息
* @param searchSourceBuilder 查询参数建造者 * @param searchSourceBuilder 查询参数建造者
*/ */
private static void setAggregations(Wrapper<?> wrapper, Map<String, String> mappingColumnMap, private static void setAggregations(Wrapper<?> wrapper, Map<String, String> mappingColumnMap,
SearchRequest.Builder searchSourceBuilder) { EntityInfo entityInfo, SearchRequest.Builder searchSourceBuilder) {
// 设置折叠(去重)字段 // 设置折叠(去重)字段
Optional.ofNullable(wrapper.distinctField) Optional.ofNullable(wrapper.distinctField)
.ifPresent(distinctField -> { .ifPresent(distinctField -> {
String realField = getRealField(distinctField, mappingColumnMap); String realField = getRealField(distinctField, mappingColumnMap, entityInfo);
searchSourceBuilder.collapse(x -> x.field(realField)); searchSourceBuilder.collapse(x -> x.field(realField));
searchSourceBuilder.aggregations(REPEAT_NUM_KEY, x -> x.cardinality(y -> y.field(realField))); searchSourceBuilder.aggregations(REPEAT_NUM_KEY, x -> x.cardinality(y -> y.field(realField)));
}); });
@ -688,7 +685,7 @@ public class WrapperProcessor {
Aggregation.Builder.ContainerBuilder root = null; Aggregation.Builder.ContainerBuilder root = null;
Aggregation.Builder.ContainerBuilder cursor = null; Aggregation.Builder.ContainerBuilder cursor = null;
for (AggregationParam aggParam : aggregationParamList) { for (AggregationParam aggParam : aggregationParamList) {
String realField = getRealField(aggParam.getField(), mappingColumnMap); String realField = getRealField(aggParam.getField(), mappingColumnMap, entityInfo);
Aggregation.Builder.ContainerBuilder builder = getRealAggregationBuilder( Aggregation.Builder.ContainerBuilder builder = getRealAggregationBuilder(
aggParam.getAggregationType(), realField, wrapper.size, wrapper.bucketOrders); aggParam.getAggregationType(), realField, wrapper.size, wrapper.bucketOrders);
// 解决同一个字段聚合多次如min(starNum), max(starNum) 字段名重复问题 // 解决同一个字段聚合多次如min(starNum), max(starNum) 字段名重复问题

View File

@ -7,6 +7,7 @@ import org.dromara.easyes.common.constants.BaseEsConstants;
import org.dromara.easyes.common.params.SFunction; import org.dromara.easyes.common.params.SFunction;
import org.dromara.easyes.common.property.GlobalConfig; import org.dromara.easyes.common.property.GlobalConfig;
import org.dromara.easyes.common.utils.StringUtils; import org.dromara.easyes.common.utils.StringUtils;
import org.dromara.easyes.core.biz.EntityInfo;
import org.dromara.easyes.core.cache.GlobalConfigCache; import org.dromara.easyes.core.cache.GlobalConfigCache;
import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandle;
@ -19,6 +20,7 @@ import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static org.dromara.easyes.common.constants.BaseEsConstants.DEFAULT_ES_ID_NAME;
import static org.dromara.easyes.common.constants.BaseEsConstants.KEYWORD_SUFFIX; import static org.dromara.easyes.common.constants.BaseEsConstants.KEYWORD_SUFFIX;
/** /**
@ -151,7 +153,7 @@ public class FieldUtils {
* @return 首字母大写后的结果 * @return 首字母大写后的结果
*/ */
public static String firstToUpperCase(String param) { public static String firstToUpperCase(String param) {
if (Objects.isNull(param) || "".equals(param)) { if (Objects.isNull(param) || param.isEmpty()) {
return ""; return "";
} }
return param.substring(0, 1).toUpperCase() + param.substring(1); return param.substring(0, 1).toUpperCase() + param.substring(1);
@ -162,12 +164,25 @@ public class FieldUtils {
* *
* @param field 原字段名 * @param field 原字段名
* @param mappingColumnMap 字段映射关系map * @param mappingColumnMap 字段映射关系map
* @param entityInfo 索引信息
* @return 实际字段名 * @return 实际字段名
*/ */
public static String getRealField(String field, Map<String, String> mappingColumnMap) { public static String getRealField(String field, Map<String, String> mappingColumnMap, EntityInfo entityInfo) {
String customField = mappingColumnMap.get(field); String customField = mappingColumnMap.get(field);
if (Objects.nonNull(customField)) { if (Objects.nonNull(customField)) {
if (entityInfo.isId2Source()) {
return customField; return customField;
}
// 直接用_id去查询, 但是有些版本需要开启集群配置: indices.id_field_data.enabled
/*
* PUT /_cluster/settings
* {
* "persistent": {
* "indices.id_field_data.enabled": true
* }
* }
*/
return entityInfo.getKeyProperty().equals(field) ? DEFAULT_ES_ID_NAME : customField;
} else { } else {
GlobalConfig.DbConfig dbConfig = GlobalConfigCache.getGlobalConfig().getDbConfig(); GlobalConfig.DbConfig dbConfig = GlobalConfigCache.getGlobalConfig().getDbConfig();
if (dbConfig.isMapUnderscoreToCamelCase()) { if (dbConfig.isMapUnderscoreToCamelCase()) {
@ -184,13 +199,19 @@ public class FieldUtils {
* @param field 字段 * @param field 字段
* @param fieldTypeMap 字段与es字段类型映射 * @param fieldTypeMap 字段与es字段类型映射
* @param mappingColumnMap 实体字段与es实际字段映射 * @param mappingColumnMap 实体字段与es实际字段映射
* @param entityInfo 索引信息
* @return 最终的字段 * @return 最终的字段
*/ */
public static String getRealFieldAndSuffix(String field, Map<String, String> fieldTypeMap, Map<String, String> mappingColumnMap) { public static String getRealFieldAndSuffix(
String field,
Map<String, String> fieldTypeMap,
Map<String, String> mappingColumnMap,
EntityInfo entityInfo
) {
GlobalConfig.DbConfig dbConfig = GlobalConfigCache.getGlobalConfig().getDbConfig(); GlobalConfig.DbConfig dbConfig = GlobalConfigCache.getGlobalConfig().getDbConfig();
String realField = getRealField(field, mappingColumnMap); String realField = getRealField(field, mappingColumnMap, entityInfo);
String fieldType = fieldTypeMap.get(field); String fieldType = fieldTypeMap.get(field);
boolean addSuffix = dbConfig.isSmartAddKeywordSuffix() && FieldType.KEYWORD_TEXT.getType().equals(fieldType); boolean addSuffix = dbConfig.isSmartAddKeywordSuffix() && FieldType.KEYWORD_TEXT.getType().equals(fieldType) && !DEFAULT_ES_ID_NAME.equals(realField);
if (addSuffix) { if (addSuffix) {
return realField + KEYWORD_SUFFIX; return realField + KEYWORD_SUFFIX;
} }
@ -224,11 +245,12 @@ public class FieldUtils {
* *
* @param fields 原字段名数组 * @param fields 原字段名数组
* @param mappingColumnMap 字段映射关系map * @param mappingColumnMap 字段映射关系map
* @param entityInfo 索引信息
* @return 实际字段数组 * @return 实际字段数组
*/ */
public static List<String> getRealFields(String[] fields, Map<String, String> mappingColumnMap) { public static List<String> getRealFields(String[] fields, Map<String, String> mappingColumnMap, EntityInfo entityInfo) {
return Arrays.stream(fields) return Arrays.stream(fields)
.map(field -> getRealField(field, mappingColumnMap)) .map(field -> getRealField(field, mappingColumnMap, entityInfo))
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
@ -237,11 +259,12 @@ public class FieldUtils {
* *
* @param fields 原字段名数组 * @param fields 原字段名数组
* @param mappingColumnMap 字段映射关系map * @param mappingColumnMap 字段映射关系map
* @param entityInfo 索引信息
* @return 实际字段数组 * @return 实际字段数组
*/ */
public static List<String> getRealFields(List<String> fields, Map<String, String> mappingColumnMap) { public static List<String> getRealFields(List<String> fields, Map<String, String> mappingColumnMap, EntityInfo entityInfo) {
return fields.stream() return fields.stream()
.map(field -> getRealField(field, mappingColumnMap)) .map(field -> getRealField(field, mappingColumnMap, entityInfo))
.collect(Collectors.toList()); .collect(Collectors.toList());
} }

View File

@ -2,6 +2,7 @@ package org.dromara.easyes.test.entity;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import org.dromara.easyes.annotation.*; import org.dromara.easyes.annotation.*;
import org.dromara.easyes.annotation.rely.*; import org.dromara.easyes.annotation.rely.*;
@ -23,6 +24,7 @@ import java.util.List;
* <p> * <p>
* Copyright © 2021 xpc1024 All Rights Reserved * Copyright © 2021 xpc1024 All Rights Reserved
**/ **/
@EqualsAndHashCode(callSuper = false)
@Data @Data
@Accessors(chain = true) @Accessors(chain = true)
@Settings(shardsNum = 3, replicasNum = 2, settingsProvider = MySettingsProvider.class) @Settings(shardsNum = 3, replicasNum = 2, settingsProvider = MySettingsProvider.class)

View File

@ -10,7 +10,6 @@ import co.elastic.clients.elasticsearch.core.SearchRequest;
import co.elastic.clients.elasticsearch.core.SearchResponse; import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.json.JsonData; import co.elastic.clients.json.JsonData;
import co.elastic.clients.transport.rest_client.RestClientOptions; import co.elastic.clients.transport.rest_client.RestClientOptions;
import org.dromara.easyes.common.constants.BaseEsConstants;
import org.dromara.easyes.core.biz.EntityInfo; import org.dromara.easyes.core.biz.EntityInfo;
import org.dromara.easyes.core.biz.EsPageInfo; import org.dromara.easyes.core.biz.EsPageInfo;
import org.dromara.easyes.core.biz.OrderByParam; import org.dromara.easyes.core.biz.OrderByParam;
@ -739,10 +738,11 @@ public class AllTest {
@Test @Test
@Order(60) @Order(60)
public void testSort() { public void testSort() {
EntityInfo entityInfo = EntityInfoHelper.getEntityInfo(Document.class);
String realField = FieldUtils.getRealField( String realField = FieldUtils.getRealField(
FieldUtils.val(Document::getStarNum), FieldUtils.val(Document::getStarNum),
EntityInfoHelper.getEntityInfo(Document.class).getMappingColumnMap() entityInfo.getMappingColumnMap(),
); entityInfo);
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>(); LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
wrapper.match(Document::getCreator, "老汉"); wrapper.match(Document::getCreator, "老汉");
@ -940,40 +940,40 @@ public class AllTest {
Assertions.assertTrue(success); Assertions.assertTrue(success);
} }
// 4.删除 // // 4.删除
@Test // @Test
@Order(76) // @Order(76)
public void testDeleteById() { // public void testDeleteById() {
int count = documentMapper.deleteById("1"); // int count = documentMapper.deleteById("1");
Assertions.assertEquals(1, count); // Assertions.assertEquals(1, count);
} // }
//
@Test // @Test
@Order(77) // @Order(77)
public void testDeleteBatchIds() { // public void testDeleteBatchIds() {
List<String> idList = Arrays.asList("2", "3", "4"); // List<String> idList = Arrays.asList("2", "3", "4");
int count = documentMapper.deleteBatchIds(idList); // int count = documentMapper.deleteBatchIds(idList);
Assertions.assertEquals(3, count); // Assertions.assertEquals(3, count);
} // }
//
@Test // @Test
@Order(78) // @Order(78)
public void testDeleteByWrapper() { // public void testDeleteByWrapper() {
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>(); // LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
wrapper.match(Document::getCreator, "老汉"); // wrapper.match(Document::getCreator, "老汉");
//
int count = documentMapper.delete(wrapper); // int count = documentMapper.delete(wrapper);
Assertions.assertEquals(18, count); // Assertions.assertEquals(18, count);
} // }
//
@Test // @Test
@Order(80) // @Order(80)
public void testDeleteIndex() { // public void testDeleteIndex() {
boolean deleted = documentMapper.deleteIndex(EntityInfoHelper.getEntityInfo(Document.class).getIndexName()); // boolean deleted = documentMapper.deleteIndex(EntityInfoHelper.getEntityInfo(Document.class).getIndexName());
boolean lockDeleted = documentMapper.deleteIndex(BaseEsConstants.LOCK_INDEX); // boolean lockDeleted = documentMapper.deleteIndex(BaseEsConstants.LOCK_INDEX);
Assertions.assertTrue(deleted); // Assertions.assertTrue(deleted);
Assertions.assertTrue(lockDeleted); // Assertions.assertTrue(lockDeleted);
} // }
@Test @Test
@Order(79) @Order(79)

View File

@ -757,7 +757,7 @@ public class XmlScannerAllTest {
FieldSortBuilder fieldSortBuilder = SortBuilders. FieldSortBuilder fieldSortBuilder = SortBuilders.
fieldSort(FieldUtils.getRealField( fieldSort(FieldUtils.getRealField(
FieldUtils.val(Document::getStarNum), FieldUtils.val(Document::getStarNum),
EntityInfoHelper.getEntityInfo(Document.class).getMappingColumnMap())); EntityInfoHelper.getEntityInfo(Document.class).getMappingColumnMap(), entityInfo.getKeyProperty()));
fieldSortBuilder.order(SortOrder.Desc); fieldSortBuilder.order(SortOrder.Desc);
wrapper.sort(fieldSortBuilder); wrapper.sort(fieldSortBuilder);
List<Document> documents = documentMapper.selectList(wrapper); List<Document> documents = documentMapper.selectList(wrapper);

View File

@ -759,7 +759,7 @@ public class AllTest {
FieldSortBuilder fieldSortBuilder = SortBuilders. FieldSortBuilder fieldSortBuilder = SortBuilders.
fieldSort(FieldUtils.getRealField( fieldSort(FieldUtils.getRealField(
FieldUtils.val(Document::getStarNum), FieldUtils.val(Document::getStarNum),
EntityInfoHelper.getEntityInfo(Document.class).getMappingColumnMap())); EntityInfoHelper.getEntityInfo(Document.class).getMappingColumnMap(), entityInfo.getKeyProperty()));
fieldSortBuilder.order(SortOrder.Desc); fieldSortBuilder.order(SortOrder.Desc);
wrapper.sort(fieldSortBuilder); wrapper.sort(fieldSortBuilder);
List<Document> documents = documentMapper.selectList(wrapper); List<Document> documents = documentMapper.selectList(wrapper);