Skip to content

Commit 033b68f

Browse files
committed
Fix BucketOperationSupport _id field exposure.
Closes #5046 Signed-off-by: Amine jaoui <[email protected]>
1 parent 2e256f2 commit 033b68f

File tree

4 files changed

+38
-24
lines changed

4 files changed

+38
-24
lines changed

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
*
3737
* @author Mark Paluch
3838
* @author Christoph Strobl
39+
* @author Amine Jaoui
3940
* @since 1.10
4041
*/
4142
public abstract class BucketOperationSupport<T extends BucketOperationSupport<T, B>, B extends OutputBuilder<B, T>>
@@ -421,12 +422,13 @@ private Outputs(Collection<Output> current, Output output) {
421422
*/
422423
protected ExposedFields asExposedFields() {
423424

425+
// The _id is always present after the bucket operation
426+
ExposedFields fields = ExposedFields.from(new ExposedField(Fields.UNDERSCORE_ID, true));
424427
// The count field is included by default when the output is not specified.
425428
if (isEmpty()) {
426-
return ExposedFields.from(new ExposedField("count", true));
429+
fields = fields.and(new ExposedField("count", true));
427430
}
428431

429-
ExposedFields fields = ExposedFields.from();
430432

431433
for (Output output : outputs) {
432434
fields = fields.and(output.getExposedField());

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

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
* @author Oliver Gierke
4848
* @author Christoph Strobl
4949
* @author Mark Paluch
50+
* @author Amine Jaoui
5051
* @since 1.3
5152
* @see <a href="https://docs.mongodb.com/manual/reference/operator/aggregation/project/">MongoDB Aggregation Framework:
5253
* $project</a>
@@ -1404,14 +1405,6 @@ private Object renderFieldValue(AggregationOperationContext context) {
14041405
return field.getTarget();
14051406
}
14061407

1407-
if (field.getTarget().equals(Fields.UNDERSCORE_ID)) {
1408-
try {
1409-
return context.getReference(field).getReferenceValue();
1410-
} catch (java.lang.IllegalArgumentException e) {
1411-
return Fields.UNDERSCORE_ID_REF;
1412-
}
1413-
}
1414-
14151408
// check whether referenced field exists in the context
14161409
return context.getReference(field).getReferenceValue();
14171410

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

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package org.springframework.data.mongodb.core.aggregation;
1717

1818
import static org.springframework.data.mongodb.core.DocumentTestUtils.getAsDocument;
19+
import static org.springframework.data.mongodb.core.aggregation.AddFieldsOperation.addField;
1920
import static org.springframework.data.mongodb.core.aggregation.Aggregation.DEFAULT_CONTEXT;
2021
import static org.springframework.data.mongodb.core.aggregation.Aggregation.bucket;
2122
import static org.springframework.data.mongodb.core.aggregation.Aggregation.group;
@@ -43,7 +44,6 @@
4344
import org.springframework.data.domain.Sort;
4445
import org.springframework.data.domain.Sort.Direction;
4546
import org.springframework.data.mongodb.core.aggregation.ConditionalOperators.Cond;
46-
import org.springframework.data.mongodb.core.aggregation.ProjectionOperationUnitTests.BookWithFieldAnnotation;
4747
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
4848
import org.springframework.data.mongodb.core.convert.NoOpDbRefResolver;
4949
import org.springframework.data.mongodb.core.convert.QueryMapper;
@@ -61,6 +61,7 @@
6161
* @author Christoph Strobl
6262
* @author Mark Paluch
6363
* @author Julia Lee
64+
* @author Amine Jaoui
6465
*/
6566
public class AggregationUnitTests {
6667

@@ -605,18 +606,22 @@ void shouldAllowInternalThisAndValueReferences() {
605606
"{\"attributeRecordArrays\": {\"$reduce\": {\"input\": \"$attributeRecordArrays\", \"initialValue\": [], \"in\": {\"$concatArrays\": [\"$$value\", \"$$this\"]}}}}"));
606607
}
607608

608-
@Test // DATAMONGO-2644
609-
void projectOnIdIsAlwaysValid() {
610-
611-
MongoMappingContext mappingContext = new MongoMappingContext();
612-
Document target = new Aggregation(bucket("start"), project("_id")).toDocument("collection-1",
613-
new TypeBasedAggregationOperationContext(BookWithFieldAnnotation.class, mappingContext,
614-
new QueryMapper(new MappingMongoConverter(NoOpDbRefResolver.INSTANCE, mappingContext)),
615-
FieldLookupPolicy.relaxed()));
609+
@Test // GH-5046
610+
void projectOnBucketIntervalId() {
616611

612+
Document target = new Aggregation(bucket("start"), project("_id")).toDocument("collection-1", DEFAULT_CONTEXT);
617613
assertThat(extractPipelineElement(target, 1, "$project")).isEqualTo(Document.parse(" { \"_id\" : 1 }"));
618614
}
619615

616+
@Test // GH-5046
617+
void addFieldFromBucketIntervalId() {
618+
619+
Document target = new Aggregation(bucket("start"), addField("bucketLabel").withValueOf("_id").build())
620+
.toDocument("collection-1", DEFAULT_CONTEXT);
621+
assertThat(extractPipelineElement(target, 1, "$addFields"))
622+
.isEqualTo(Document.parse(" { \"bucketLabel\" : \"$_id\" }"));
623+
}
624+
620625
@Test // GH-3898
621626
void shouldNotConvertIncludeExcludeValuesForProjectOperation() {
622627

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

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@
1515
*/
1616
package org.springframework.data.mongodb.core.aggregation;
1717

18-
import static org.assertj.core.api.Assertions.*;
19-
import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
18+
import static org.assertj.core.api.Assertions.assertThat;
19+
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
20+
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
21+
import static org.springframework.data.mongodb.core.aggregation.Aggregation.bucket;
2022

2123
import org.bson.Document;
2224
import org.junit.jupiter.api.Test;
@@ -25,6 +27,7 @@
2527
* Unit tests for {@link BucketOperation}.
2628
*
2729
* @author Mark Paluch
30+
* @author Amine Jaoui
2831
*/
2932
public class BucketOperationUnitTests {
3033

@@ -194,15 +197,26 @@ public void shouldRenderSumWithOwnOutputExpression() {
194197
.isEqualTo(Document.parse("{ total : { $multiply: [ {$add : [\"$netPrice\", \"$tax\"]}, 5] } }"));
195198
}
196199

197-
@Test // DATAMONGO-1552
198-
public void shouldExposeDefaultCountField() {
200+
@Test // GH-5046
201+
public void shouldExposeDefaultFields() {
199202

200203
BucketOperation operation = bucket("field");
201204

202-
assertThat(operation.getFields().exposesSingleFieldOnly()).isTrue();
205+
assertThat(operation.getFields().exposesNoNonSyntheticFields()).isTrue();
206+
assertThat(operation.getFields().getField(Fields.UNDERSCORE_ID)).isNotNull();
203207
assertThat(operation.getFields().getField("count")).isNotNull();
204208
}
205209

210+
@Test // GH-5046
211+
public void shouldExposeIDWhenCustomOutputField() {
212+
213+
BucketOperation operation = bucket("field").andOutputCount().as("score");
214+
215+
assertThat(operation.getFields().getField(Fields.UNDERSCORE_ID)).isNotNull();
216+
assertThat(operation.getFields().getField("score")).isNotNull();
217+
assertThat(operation.getFields().getField("count")).isNull();
218+
}
219+
206220
private static Document extractOutput(Document fromBucketClause) {
207221
return (Document) ((Document) fromBucketClause.get("$bucket")).get("output");
208222
}

0 commit comments

Comments
 (0)