DATAMONGO-788 - Projection operations do not render synthetic fields properly.
Introduced boolean isSynthetic() attribute to FieldReference to determine if the given reference points to a synthetic field, as this controls whether we render a simple include (1) or a concrete reference ($fieldName) E.g. isSynthetic() would be true for a field reference to _id. Original pull request: #90.
This commit is contained in:
committed by
Oliver Gierke
parent
49af31bb6e
commit
8b3da2d7f9
@@ -334,6 +334,13 @@ public class ExposedFields implements Iterable<ExposedField> {
|
||||
this.field = field;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public boolean isSynthetic() {
|
||||
return field.synthetic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw, unqualified reference, i.e. the field reference without a {@literal $} prefix.
|
||||
*
|
||||
|
||||
@@ -508,7 +508,7 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
|
||||
// check whether referenced field exists in the context
|
||||
FieldReference reference = context.getReference(field.getTarget());
|
||||
|
||||
if (field.getName().equals(field.getTarget())) {
|
||||
if (field.getName().equals(field.getTarget()) && reference.isSynthetic()) {
|
||||
|
||||
// render field as included
|
||||
return 1;
|
||||
|
||||
@@ -85,6 +85,7 @@ public class AggregationTests {
|
||||
mongoTemplate.dropCollection(Product.class);
|
||||
mongoTemplate.dropCollection(UserWithLikes.class);
|
||||
mongoTemplate.dropCollection(DATAMONGO753.class);
|
||||
mongoTemplate.dropCollection(DATAMONGO788.class);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -520,6 +521,36 @@ public class AggregationTests {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-788
|
||||
*/
|
||||
@Test
|
||||
public void referencesToGroupIdsShouldBeRenderedProperly() {
|
||||
|
||||
mongoTemplate.insert(new DATAMONGO788(1, 1));
|
||||
mongoTemplate.insert(new DATAMONGO788(1, 1));
|
||||
mongoTemplate.insert(new DATAMONGO788(1, 1));
|
||||
mongoTemplate.insert(new DATAMONGO788(2, 1));
|
||||
mongoTemplate.insert(new DATAMONGO788(2, 1));
|
||||
|
||||
AggregationOperation projectFirst = Aggregation.project("x", "y").and("xField").as("x").and("yField").as("y");
|
||||
AggregationOperation group = Aggregation.group("x", "y").count().as("xPerY");
|
||||
AggregationOperation project = Aggregation.project("xPerY", "x", "y").andExclude("_id");
|
||||
|
||||
TypedAggregation<DATAMONGO788> aggregation = Aggregation.newAggregation(DATAMONGO788.class, projectFirst, group,
|
||||
project);
|
||||
AggregationResults<DBObject> aggResults = mongoTemplate.aggregate(aggregation, DBObject.class);
|
||||
List<DBObject> items = aggResults.getMappedResults();
|
||||
|
||||
assertThat(items.size(), is(2));
|
||||
assertThat((Integer) items.get(0).get("xPerY"), is(2));
|
||||
assertThat((Integer) items.get(0).get("x"), is(2));
|
||||
assertThat((Integer) items.get(0).get("y"), is(1));
|
||||
assertThat((Integer) items.get(1).get("xPerY"), is(3));
|
||||
assertThat((Integer) items.get(1).get("x"), is(1));
|
||||
assertThat((Integer) items.get(1).get("y"), is(1));
|
||||
}
|
||||
|
||||
private void assertLikeStats(LikeStats like, String id, long count) {
|
||||
|
||||
assertThat(like, is(notNullValue()));
|
||||
@@ -585,4 +616,22 @@ public class AggregationTests {
|
||||
this.up = up;
|
||||
}
|
||||
}
|
||||
|
||||
static class DATAMONGO788 {
|
||||
|
||||
int x;
|
||||
int y;
|
||||
int xField;
|
||||
int yField;
|
||||
|
||||
public DATAMONGO788() {}
|
||||
|
||||
public DATAMONGO788(int x, int y) {
|
||||
this.x = x;
|
||||
this.xField = x;
|
||||
this.y = y;
|
||||
this.yField = y;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,12 +15,19 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.aggregation;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
|
||||
import static org.springframework.data.mongodb.core.query.Criteria.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.springframework.data.mongodb.core.DBObjectUtils;
|
||||
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link Aggregation}.
|
||||
@@ -94,4 +101,23 @@ public class AggregationUnitTests {
|
||||
project("a", "b") // b should still be available
|
||||
).toDbObject("foo", Aggregation.DEFAULT_CONTEXT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-788
|
||||
*/
|
||||
@Test
|
||||
public void referencesToGroupIdsShouldBeRenderedAsReferences() {
|
||||
|
||||
DBObject agg = newAggregation( //
|
||||
project("a"), //
|
||||
group("a").count().as("aCnt"), //
|
||||
project("aCnt", "a") //
|
||||
).toDbObject("foo", Aggregation.DEFAULT_CONTEXT);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
DBObject secondProjection = ((List<DBObject>) agg.get("pipeline")).get(2);
|
||||
DBObject fields = DBObjectUtils.getAsDBObject(secondProjection, "$project");
|
||||
assertThat((Integer) fields.get("aCnt"), is(1));
|
||||
assertThat((String) fields.get("a"), is("$_id.a"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user