From d2f90bae5dfd22f6464b036028698f543099ae2c Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Mon, 27 Jul 2015 13:45:12 +0200 Subject: [PATCH] DATAMONGO-1254 - Grouping after projection in aggregation now uses correct aliased field name. We now push the aliased field name down the aggregation pipeline for projections including operations. This allows to reference them in a later stage. Prior to this change the field reference was potentially resolved to the target field of the operation which did not result in an error but lead to false results. Original pull request: #311. --- .../core/aggregation/ProjectionOperation.java | 16 ++++++++ .../aggregation/AggregationUnitTests.java | 38 ++++++++++++++++++- 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperation.java index cedd036ee..68947352a 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperation.java @@ -21,6 +21,7 @@ import java.util.Collections; import java.util.List; import org.springframework.data.mongodb.core.aggregation.ExposedFields.ExposedField; +import org.springframework.data.mongodb.core.aggregation.Fields.AggregationField; import org.springframework.data.mongodb.core.aggregation.ProjectionOperation.ProjectionOperationBuilder.FieldProjection; import org.springframework.util.Assert; @@ -40,6 +41,7 @@ import com.mongodb.DBObject; * @author Tobias Trelle * @author Thomas Darimont * @author Oliver Gierke + * @author Christoph Strobl * @since 1.3 */ public class ProjectionOperation implements FieldsExposingAggregationOperation { @@ -763,6 +765,20 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation { return field; } + /* + * (non-Javadoc) + * @see org.springframework.data.mongodb.core.aggregation.ProjectionOperation.Projection#getExposedField() + */ + @Override + public ExposedField getExposedField() { + + if (!getField().isAliased()) { + return super.getExposedField(); + } + + return new ExposedField(new AggregationField(getField().getName()), true); + } + /** * Creates a new instance of this {@link OperationProjection} with the given alias. * diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AggregationUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AggregationUnitTests.java index 3116560f9..7c8d3d3db 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AggregationUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AggregationUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2014 the original author or authors. + * Copyright 2013-2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,6 +30,7 @@ import org.junit.rules.ExpectedException; import org.springframework.data.domain.Sort.Direction; import com.mongodb.BasicDBObject; +import com.mongodb.BasicDBObjectBuilder; import com.mongodb.DBObject; /** @@ -37,6 +38,7 @@ import com.mongodb.DBObject; * * @author Oliver Gierke * @author Thomas Darimont + * @author Christoph Strobl */ public class AggregationUnitTests { @@ -283,6 +285,40 @@ public class AggregationUnitTests { is((DBObject) new BasicDBObject("_id", "$someKey").append("doc", new BasicDBObject("$first", "$$ROOT")))); } + /** + * @see DATAMONGO-1254 + */ + @Test + public void shouldExposeAliasedFieldnameForProjectionsIncludingOperationsDownThePipeline() { + + DBObject agg = Aggregation.newAggregation(// + project("date") // + .and("tags").minus(10).as("tags_count")// + , group("date")// + .sum("tags_count").as("count")// + ).toDbObject("foo", Aggregation.DEFAULT_CONTEXT); + + DBObject group = extractPipelineElement(agg, 1, "$group"); + assertThat(getAsDBObject(group, "count"), is(new BasicDBObjectBuilder().add("$sum", "$tags_count").get())); + } + + /** + * @see DATAMONGO-1254 + */ + @Test + public void shouldUseAliasedFieldnameForProjectionsIncludingOperationsDownThePipelineWhenUsingSpEL() { + + DBObject agg = Aggregation.newAggregation(// + project("date") // + .andExpression("tags-10")// + , group("date")// + .sum("tags_count").as("count")// + ).toDbObject("foo", Aggregation.DEFAULT_CONTEXT); + + DBObject group = extractPipelineElement(agg, 1, "$group"); + assertThat(getAsDBObject(group, "count"), is(new BasicDBObjectBuilder().add("$sum", "$tags_count").get())); + } + private DBObject extractPipelineElement(DBObject agg, int index, String operation) { List pipeline = (List) agg.get("pipeline");