Browse Source

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.
pull/313/merge
Christoph Strobl 11 years ago committed by Oliver Gierke
parent
commit
6f0ac7f0c2
  1. 16
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperation.java
  2. 38
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AggregationUnitTests.java

16
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 java.util.List;
import org.springframework.data.mongodb.core.aggregation.ExposedFields.ExposedField; 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.data.mongodb.core.aggregation.ProjectionOperation.ProjectionOperationBuilder.FieldProjection;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@ -40,6 +41,7 @@ import com.mongodb.DBObject;
* @author Tobias Trelle * @author Tobias Trelle
* @author Thomas Darimont * @author Thomas Darimont
* @author Oliver Gierke * @author Oliver Gierke
* @author Christoph Strobl
* @since 1.3 * @since 1.3
*/ */
public class ProjectionOperation implements FieldsExposingAggregationOperation { public class ProjectionOperation implements FieldsExposingAggregationOperation {
@ -763,6 +765,20 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
return field; 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. * Creates a new instance of this {@link OperationProjection} with the given alias.
* *

38
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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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 org.springframework.data.domain.Sort.Direction;
import com.mongodb.BasicDBObject; import com.mongodb.BasicDBObject;
import com.mongodb.BasicDBObjectBuilder;
import com.mongodb.DBObject; import com.mongodb.DBObject;
/** /**
@ -37,6 +38,7 @@ import com.mongodb.DBObject;
* *
* @author Oliver Gierke * @author Oliver Gierke
* @author Thomas Darimont * @author Thomas Darimont
* @author Christoph Strobl
*/ */
public class AggregationUnitTests { public class AggregationUnitTests {
@ -283,6 +285,40 @@ public class AggregationUnitTests {
is((DBObject) new BasicDBObject("_id", "$someKey").append("doc", new BasicDBObject("$first", "$$ROOT")))); 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) { private DBObject extractPipelineElement(DBObject agg, int index, String operation) {
List<DBObject> pipeline = (List<DBObject>) agg.get("pipeline"); List<DBObject> pipeline = (List<DBObject>) agg.get("pipeline");

Loading…
Cancel
Save