From e092d162d9c3c78697fc8ab33c779e7644c7e472 Mon Sep 17 00:00:00 2001 From: DDT <1786035110@qq.com> Date: Thu, 17 Sep 2026 22:26:45 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=AE=A1=E9=81=93?= =?UTF-8?q?=E8=81=9A=E5=90=88=E8=B6=85=E8=BF=87=E4=B8=A4=E4=B8=AA=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=E6=97=B6=E4=B8=A2=E5=A4=B1=E5=90=8E=E7=BB=AD=E8=81=9A?= =?UTF-8?q?=E5=90=88=E5=AD=97=E6=AE=B5=E7=9A=84=E9=97=AE=E9=A2=98=20(#167)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 自底向上构建聚合树, 避免在子聚合挂载前提前 build 导致快照丢失 --- .../easyes/core/kernel/WrapperProcessor.java | 72 ++++++++++++------- 1 file changed, 48 insertions(+), 24 deletions(-) diff --git a/easy-es-core/src/main/java/org/dromara/easyes/core/kernel/WrapperProcessor.java b/easy-es-core/src/main/java/org/dromara/easyes/core/kernel/WrapperProcessor.java index 582f25c..fbfd073 100644 --- a/easy-es-core/src/main/java/org/dromara/easyes/core/kernel/WrapperProcessor.java +++ b/easy-es-core/src/main/java/org/dromara/easyes/core/kernel/WrapperProcessor.java @@ -898,41 +898,65 @@ private static void setAggregations(Wrapper wrapper, Map mapp return; } - // 构建聚合树 - String rootName = null; - Aggregation.Builder.ContainerBuilder root = null; - Aggregation.Builder.ContainerBuilder cursor = null; + // 拆分管道聚合与普通聚合 + List pipelineList = new ArrayList<>(); + List normalList = new ArrayList<>(); for (AggregationParam aggParam : aggregationParamList) { + if (aggParam.isEnablePipeline()) { + pipelineList.add(aggParam); + } else { + normalList.add(aggParam); + } + } + + // 非管道聚合, 平铺到顶层 + for (AggregationParam aggParam : normalList) { String realField = getRealFieldAndSuffix(aggParam.getField(), mappingColumnMap, entityInfo); Aggregation.Builder.ContainerBuilder builder = getRealAggregationBuilder( aggParam.getAggregationType(), realField, wrapper.size, wrapper.bucketOrders); // 解决同一个字段聚合多次,如min(starNum), max(starNum) 字段名重复问题 String aggName = aggParam.getName() + aggParam.getAggregationType().getValue(); - if (aggParam.isEnablePipeline()) { - // 管道聚合, 构造聚合树 - if (root == null) { - root = builder; - rootName = aggName; - cursor = root; - } else { - Aggregation agg = builder.build(); - cursor.aggregations(aggName, agg); - // 解决max、min、avg和sum聚合函数不支持sub-aggregations的问题 - if (agg._kind().equals(Aggregation.Kind.Terms)) { - cursor = builder; - } + searchSourceBuilder.aggregations(aggName, builder.build()); + } + + // 管道聚合: 按 terms 分层, metric 挂在当前最深层; 自底向上构建嵌套树, + // 避免过早 build 导致第 3 个及之后的字段丢失 (issue #167) + Aggregation innerAgg = null; + String innerName = null; + String rootName = null; + List metricNames = new ArrayList<>(); + List metricBuilders = new ArrayList<>(); + for (int i = pipelineList.size() - 1; i >= 0; i--) { + AggregationParam aggParam = pipelineList.get(i); + String realField = getRealFieldAndSuffix(aggParam.getField(), mappingColumnMap, entityInfo); + Aggregation.Builder.ContainerBuilder builder = getRealAggregationBuilder( + aggParam.getAggregationType(), realField, wrapper.size, wrapper.bucketOrders); + String aggName = aggParam.getName() + aggParam.getAggregationType().getValue(); + if (aggParam.getAggregationType() == AggregationTypeEnum.TERMS) { + for (int m = 0; m < metricBuilders.size(); m++) { + builder.aggregations(metricNames.get(m), metricBuilders.get(m).build()); } - } else { - // 非管道聚合 - if (builder != null) { - searchSourceBuilder.aggregations(aggName, builder.build()); + metricNames.clear(); + metricBuilders.clear(); + if (innerAgg != null) { + builder.aggregations(innerName, innerAgg); } + rootName = aggName; + innerAgg = builder.build(); + innerName = aggName; + } else { + metricNames.add(aggName); + metricBuilders.add(builder); } - } - if (root != null) { - searchSourceBuilder.aggregations(rootName, root.build()); + // 管道聚合中未挂在 terms 下的 metric(首个或全部为 metric 的罕见场景), 平铺到顶层 + for (int m = 0; m < metricBuilders.size(); m++) { + searchSourceBuilder.aggregations(metricNames.get(m), metricBuilders.get(m).build()); } + if (innerAgg != null) { + searchSourceBuilder.aggregations(rootName, innerAgg); + } + if (!GlobalConfigCache.getGlobalConfig().getDbConfig().isEnableAggHits()) { // 配置关闭了聚合返回结果集Hits, 可提升查询效率