Browse Source

DATAMONGO-1893 - Polishing.

Inherit fields from previous operation if at least one field is excluded. Extend FieldsExposingAggregationOperation to conditionally inherit fields.

Backport to Java 6 code.

Original pull request: #538.
pull/553/head
Mark Paluch 8 years ago
parent
commit
e8d3c9e932
  1. 4
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationOperationRenderer.java
  2. 10
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/BucketOperationSupport.java
  3. 10
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/CountOperation.java
  4. 10
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/FacetOperation.java
  5. 13
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/FieldsExposingAggregationOperation.java
  6. 10
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/GraphLookupOperation.java
  7. 10
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/GroupOperation.java
  8. 10
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/LookupOperation.java
  9. 35
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperation.java
  10. 10
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ReplaceRootOperation.java
  11. 8
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/UnwindOperation.java
  12. 48
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperationUnitTests.java
  13. 29
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/TypeBasedAggregationOperationContextUnitTests.java

4
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationOperationRenderer.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2016-2018 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.
@ -60,7 +60,7 @@ class AggregationOperationRenderer { @@ -60,7 +60,7 @@ class AggregationOperationRenderer {
FieldsExposingAggregationOperation exposedFieldsOperation = (FieldsExposingAggregationOperation) operation;
ExposedFields fields = exposedFieldsOperation.getFields();
if (operation instanceof InheritsFieldsAggregationOperation) {
if (operation instanceof InheritsFieldsAggregationOperation || exposedFieldsOperation.inheritsFields()) {
contextToUse = new InheritingExposedFieldsAggregationOperationContext(fields, contextToUse);
} else {
contextToUse = fields.exposesNoFields() ? DEFAULT_CONTEXT

10
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/BucketOperationSupport.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2016-2018 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.
@ -169,6 +169,14 @@ public abstract class BucketOperationSupport<T extends BucketOperationSupport<T, @@ -169,6 +169,14 @@ public abstract class BucketOperationSupport<T extends BucketOperationSupport<T,
return outputs.asExposedFields();
}
/* (non-Javadoc)
* @see org.springframework.data.mongodb.core.aggregation.FieldsExposingAggregationOperation#inheritsFields()
*/
@Override
public boolean inheritsFields() {
return false;
}
/**
* Implementation hook to create a new bucket operation.
*

10
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/CountOperation.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2016-2018 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.
@ -62,6 +62,14 @@ public class CountOperation implements FieldsExposingAggregationOperation { @@ -62,6 +62,14 @@ public class CountOperation implements FieldsExposingAggregationOperation {
return ExposedFields.from(new ExposedField(fieldName, true));
}
/* (non-Javadoc)
* @see org.springframework.data.mongodb.core.aggregation.FieldsExposingAggregationOperation#inheritsFields()
*/
@Override
public boolean inheritsFields() {
return false;
}
/**
* Builder for {@link CountOperation}.
*

10
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/FacetOperation.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2016-2017 the original author or authors.
* Copyright 2016-2018 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.
@ -96,6 +96,14 @@ public class FacetOperation implements FieldsExposingAggregationOperation { @@ -96,6 +96,14 @@ public class FacetOperation implements FieldsExposingAggregationOperation {
return facets.asExposedFields();
}
/* (non-Javadoc)
* @see org.springframework.data.mongodb.core.aggregation.FieldsExposingAggregationOperation#inheritsFields()
*/
@Override
public boolean inheritsFields() {
return false;
}
/**
* Builder for {@link FacetOperation} by adding existing and the new pipeline of {@link AggregationOperation} to the
* new {@link FacetOperation}.

13
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/FieldsExposingAggregationOperation.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2013-2016 the original author or authors.
* Copyright 2013-2018 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.
@ -34,10 +34,13 @@ public interface FieldsExposingAggregationOperation extends AggregationOperation @@ -34,10 +34,13 @@ public interface FieldsExposingAggregationOperation extends AggregationOperation
ExposedFields getFields();
/**
* Marker interface for {@link AggregationOperation} that inherits fields from previous operations.
* @return {@literal true} to conditionally inherit fields from previous operations.
* @since 1.10.12
*/
static interface InheritsFieldsAggregationOperation extends FieldsExposingAggregationOperation {
}
boolean inheritsFields();
/**
* Marker interface for {@link AggregationOperation} that inherits fields from previous operations.
*/
static interface InheritsFieldsAggregationOperation extends FieldsExposingAggregationOperation {}
}

10
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/GraphLookupOperation.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2016-2017 the original author or authors.
* Copyright 2016-2018 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.
@ -132,6 +132,14 @@ public class GraphLookupOperation implements InheritsFieldsAggregationOperation @@ -132,6 +132,14 @@ public class GraphLookupOperation implements InheritsFieldsAggregationOperation
return ExposedFields.from(new ExposedField(as, true));
}
/* (non-Javadoc)
* @see org.springframework.data.mongodb.core.aggregation.FieldsExposingAggregationOperation#inheritsFields()
*/
@Override
public boolean inheritsFields() {
return true;
}
/**
* @author Mark Paluch
*/

10
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/GroupOperation.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2013-2017 the original author or authors.
* Copyright 2013-2018 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.
@ -395,6 +395,14 @@ public class GroupOperation implements FieldsExposingAggregationOperation { @@ -395,6 +395,14 @@ public class GroupOperation implements FieldsExposingAggregationOperation {
return fields;
}
/* (non-Javadoc)
* @see org.springframework.data.mongodb.core.aggregation.FieldsExposingAggregationOperation#inheritsFields()
*/
@Override
public boolean inheritsFields() {
return false;
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.aggregation.AggregationOperation#toDBObject(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)

10
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/LookupOperation.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2016-2017 the original author or authors.
* Copyright 2016-2018 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.
@ -73,6 +73,14 @@ public class LookupOperation implements FieldsExposingAggregationOperation, Inhe @@ -73,6 +73,14 @@ public class LookupOperation implements FieldsExposingAggregationOperation, Inhe
return ExposedFields.from(as);
}
/* (non-Javadoc)
* @see org.springframework.data.mongodb.core.aggregation.FieldsExposingAggregationOperation#inheritsFields()
*/
@Override
public boolean inheritsFields() {
return true;
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.aggregation.AggregationOperation#toDBObject(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)

35
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperation.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2013-2017 the original author or authors.
* Copyright 2013-2018 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.
@ -47,13 +47,12 @@ import com.mongodb.DBObject; @@ -47,13 +47,12 @@ import com.mongodb.DBObject;
* @author Christoph Strobl
* @author Mark Paluch
* @since 1.3
* @see <a href="https://docs.mongodb.com/manual/reference/operator/aggregation/project/">MongoDB Aggregation Framework: $project</a>
* @see <a href="https://docs.mongodb.com/manual/reference/operator/aggregation/project/">MongoDB Aggregation Framework:
* $project</a>
*/
public class ProjectionOperation implements FieldsExposingAggregationOperation {
private static final List<Projection> NONE = Collections.emptyList();
private static final String EXCLUSION_ERROR = "Exclusion of field %s not allowed. Projections by the mongodb "
+ "aggregation framework only support the exclusion of the %s field!";
private final List<Projection> projections;
@ -183,6 +182,25 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation { @@ -183,6 +182,25 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
return fields;
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.aggregation.FieldsExposingAggregationOperation#inheritsFields()
*/
@Override
public boolean inheritsFields() {
for (Projection projection : projections) {
if (projection instanceof FieldProjection) {
if (((FieldProjection) projection).isExcluded()) {
return true;
}
}
}
return false;
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.aggregation.AggregationOperation#toDBObject(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
@ -1332,6 +1350,13 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation { @@ -1332,6 +1350,13 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
return projections;
}
/**
* @return {@literal true} if this field is excluded.
*/
public boolean isExcluded() {
return Boolean.FALSE.equals(value);
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.aggregation.ProjectionOperation.Projection#toDBObject(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
@ -1639,7 +1664,7 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation { @@ -1639,7 +1664,7 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
/**
* @author Thomas Darimont
*/
static class ExpressionProjection extends Projection {
static class ExpressionProjection extends ProjectionOperation.Projection {
private final AggregationExpression expression;
private final Field field;

10
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ReplaceRootOperation.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2016-2017 the original author or authors.
* Copyright 2016-2018 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.
@ -95,6 +95,14 @@ public class ReplaceRootOperation implements FieldsExposingAggregationOperation @@ -95,6 +95,14 @@ public class ReplaceRootOperation implements FieldsExposingAggregationOperation
return ExposedFields.from();
}
/* (non-Javadoc)
* @see org.springframework.data.mongodb.core.aggregation.FieldsExposingAggregationOperation#inheritsFields()
*/
@Override
public boolean inheritsFields() {
return false;
}
/**
* Builder for {@link ReplaceRootOperation}.
*

8
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/UnwindOperation.java

@ -117,6 +117,14 @@ public class UnwindOperation @@ -117,6 +117,14 @@ public class UnwindOperation
return arrayIndex != null ? ExposedFields.from(arrayIndex) : ExposedFields.from();
}
/* (non-Javadoc)
* @see org.springframework.data.mongodb.core.aggregation.FieldsExposingAggregationOperation#inheritsFields()
*/
@Override
public boolean inheritsFields() {
return true;
}
/**
* Get a builder that allows creation of {@link LookupOperation}.
*

48
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperationUnitTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2013-2017 the original author or authors.
* Copyright 2013-2018 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.
@ -211,9 +211,19 @@ public class ProjectionOperationUnitTests { @@ -211,9 +211,19 @@ public class ProjectionOperationUnitTests {
public void excludeShouldAllowExclusionOfFieldsOtherThanUnderscoreId/* since MongoDB 3.4 */() {
ProjectionOperation projectionOp = new ProjectionOperation().andExclude("foo");
Document document = projectionOp.toDocument(Aggregation.DEFAULT_CONTEXT);
Document projectClause = DocumentTestUtils.getAsDocument(document, PROJECT);
assertThat((Integer) projectClause.get("foo")).isEqualTo(0);
DBObject document = projectionOp.toDBObject(Aggregation.DEFAULT_CONTEXT);
DBObject projectClause = DBObjectTestUtils.getAsDBObject(document, PROJECT);
assertThat(projectionOp.inheritsFields(), is(true));
assertThat((Integer) projectClause.get("foo"), is(0));
}
@Test // DATAMONGO-1893
public void includeShouldNotInheritFields() {
ProjectionOperation projectionOp = new ProjectionOperation().andInclude("foo");
assertThat(projectionOp.inheritsFields(), is(false));
}
@Test // DATAMONGO-758
@ -1548,14 +1558,13 @@ public class ProjectionOperationUnitTests { @@ -1548,14 +1558,13 @@ public class ProjectionOperationUnitTests {
.andApply(AggregationFunctionExpressions.MULTIPLY.of(Fields.field("total"), Fields.field("discounted")))) //
.as("finalTotal").toDBObject(Aggregation.DEFAULT_CONTEXT);
assertThat(agg,
is(JSON.parse("{ $project:{ \"finalTotal\" : { \"$let\": {" + //
"\"vars\": {" + //
"\"total\": { \"$add\": [ \"$price\", \"$tax\" ] }," + //
"\"discounted\": { \"$cond\": { \"if\": \"$applyDiscount\", \"then\": 0.9, \"else\": 1.0 } }" + //
"}," + //
"\"in\": { \"$multiply\": [ \"$$total\", \"$$discounted\" ] }" + //
"}}}}")));
assertThat(agg, is(JSON.parse("{ $project:{ \"finalTotal\" : { \"$let\": {" + //
"\"vars\": {" + //
"\"total\": { \"$add\": [ \"$price\", \"$tax\" ] }," + //
"\"discounted\": { \"$cond\": { \"if\": \"$applyDiscount\", \"then\": 0.9, \"else\": 1.0 } }" + //
"}," + //
"\"in\": { \"$multiply\": [ \"$$total\", \"$$discounted\" ] }" + //
"}}}}")));
}
@Test // DATAMONGO-1538
@ -1572,14 +1581,13 @@ public class ProjectionOperationUnitTests { @@ -1572,14 +1581,13 @@ public class ProjectionOperationUnitTests {
AggregationFunctionExpressions.MULTIPLY.of(Fields.field("total"), Fields.field("discounted")))
.as("finalTotal").toDBObject(Aggregation.DEFAULT_CONTEXT);
assertThat(agg,
is(JSON.parse("{ $project:{ \"finalTotal\" : { \"$let\": {" + //
"\"vars\": {" + //
"\"total\": { \"$add\": [ \"$price\", \"$tax\" ] }," + //
"\"discounted\": { \"$cond\": { \"if\": \"$applyDiscount\", \"then\": 0.9, \"else\": 1.0 } }" + //
"}," + //
"\"in\": { \"$multiply\": [ \"$$total\", \"$$discounted\" ] }" + //
"}}}}")));
assertThat(agg, is(JSON.parse("{ $project:{ \"finalTotal\" : { \"$let\": {" + //
"\"vars\": {" + //
"\"total\": { \"$add\": [ \"$price\", \"$tax\" ] }," + //
"\"discounted\": { \"$cond\": { \"if\": \"$applyDiscount\", \"then\": 0.9, \"else\": 1.0 } }" + //
"}," + //
"\"in\": { \"$multiply\": [ \"$$total\", \"$$discounted\" ] }" + //
"}}}}")));
}
@Test // DATAMONGO-1548

29
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/TypeBasedAggregationOperationContextUnitTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2013-2017 the original author or authors.
* Copyright 2013-2018 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.
@ -22,6 +22,8 @@ import static org.springframework.data.mongodb.core.aggregation.Aggregation.*; @@ -22,6 +22,8 @@ import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
import static org.springframework.data.mongodb.core.aggregation.Fields.*;
import static org.springframework.data.mongodb.test.util.IsBsonObject.*;
import lombok.AllArgsConstructor;
import java.util.Arrays;
import java.util.List;
@ -34,7 +36,7 @@ import org.mockito.runners.MockitoJUnitRunner; @@ -34,7 +36,7 @@ import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.PersistenceConstructor;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.mapping.model.MappingException;
import org.springframework.data.mongodb.core.aggregation.ExposedFields.DirectFieldReference;
@ -196,6 +198,20 @@ public class TypeBasedAggregationOperationContextUnitTests { @@ -196,6 +198,20 @@ public class TypeBasedAggregationOperationContextUnitTests {
.containing("age", "$age.value"));
}
@Test // DATAMONGO-1893
public void considersIncludedFieldsFromSingleExclusionsCorrectly() {
AggregationOperationContext context = getContext(FooPerson.class);
TypedAggregation<FooPerson> agg = newAggregation(FooPerson.class, project() //
.andExclude("name"), sort(new Sort("age.value", "lastName")));
DBObject dbo = agg.toDbObject("person", context);
DBObject sort = getPipelineElementFromAggregationAt(dbo, 1);
assertThat(getAsDBObject(sort, "$sort"),
is(equalTo((DBObject) new BasicDBObject("age.value", 1).append("last_name", 1))));
}
@Test // DATAMONGO-1133
public void shouldHonorAliasedFieldsInGroupExpressions() {
@ -352,18 +368,13 @@ public class TypeBasedAggregationOperationContextUnitTests { @@ -352,18 +368,13 @@ public class TypeBasedAggregationOperationContextUnitTests {
}
@Document(collection = "person")
@AllArgsConstructor
public static class FooPerson {
final ObjectId id;
final String name;
@org.springframework.data.mongodb.core.mapping.Field("last_name") final String lastName;
final Age age;
@PersistenceConstructor
FooPerson(ObjectId id, String name, Age age) {
this.id = id;
this.name = name;
this.age = age;
}
}
public static class Age {

Loading…
Cancel
Save