Skip to content

Commit e1faf26

Browse files
sxhinzvcchristophstrobl
authored andcommitted
Fix mapping custom field names in downstream stages in TypedAggregation pipelines.
Use the root AggregationOperationContext in nested ExposedFieldsAggregationOperationContext to properly apply mapping for domain properties that use @field. Closes #4443 Original Pull Request: #4459
1 parent a169203 commit e1faf26

File tree

3 files changed

+46
-3
lines changed

3 files changed

+46
-3
lines changed

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

+5
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,11 @@ public Document getMappedObject(Document document, @Nullable Class<?> type) {
6767
* (non-Javadoc)
6868
* @see org.springframework.data.mongodb.core.aggregation.AggregationOperationContext#getReference(org.springframework.data.mongodb.core.aggregation.ExposedFields.AvailableField)
6969
*/
70+
@Override
71+
public Document getMappedObject(Document document) {
72+
return rootContext.getMappedObject(document);
73+
}
74+
7075
@Override
7176
public FieldReference getReference(Field field) {
7277

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

+21-2
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@
8787
* @author Maninder Singh
8888
* @author Sergey Shcherbakov
8989
* @author Minsu Kim
90+
* @author Julia Lee
9091
*/
9192
@ExtendWith(MongoTemplateExtension.class)
9293
public class AggregationTests {
@@ -116,7 +117,7 @@ private void cleanDb() {
116117

117118
mongoTemplate.flush(Product.class, UserWithLikes.class, DATAMONGO753.class, Data.class, DATAMONGO788.class,
118119
User.class, Person.class, Reservation.class, Venue.class, MeterData.class, LineItem.class, InventoryItem.class,
119-
Sales.class, Sales2.class, Employee.class, Art.class, Venue.class);
120+
Sales.class, Sales2.class, Employee.class, Art.class, Venue.class, Item.class);
120121

121122
mongoTemplate.dropCollection(INPUT_COLLECTION);
122123
mongoTemplate.dropCollection("personQueryTemp");
@@ -1962,6 +1963,23 @@ void considersMongoIdWithinTypedCollections() {
19621963
assertThat(aggregate.getMappedResults()).contains(widget);
19631964
}
19641965

1966+
@Test // GH-4443
1967+
void shouldHonorFieldAliasesForFieldReferencesUsingFieldExposingOperation() {
1968+
1969+
Item item1 = Item.builder().itemId("1").tags(Arrays.asList("a", "b")).build();
1970+
Item item2 = Item.builder().itemId("1").tags(Arrays.asList("a", "c")).build();
1971+
mongoTemplate.insert(Arrays.asList(item1, item2), Item.class);
1972+
1973+
TypedAggregation<Item> aggregation = newAggregation(Item.class,
1974+
match(where("itemId").is("1")),
1975+
unwind("tags"),
1976+
match(where("itemId").is("1").and("tags").is("c")));
1977+
AggregationResults<Document> results = mongoTemplate.aggregate(aggregation, Document.class);
1978+
List<Document> mappedResults = results.getMappedResults();
1979+
assertThat(mappedResults).hasSize(1);
1980+
assertThat(mappedResults.get(0)).containsEntry("item_id", "1");
1981+
}
1982+
19651983
private void createUsersWithReferencedPersons() {
19661984

19671985
mongoTemplate.dropCollection(User.class);
@@ -2220,7 +2238,7 @@ static class Sales {
22202238
List<Item> items;
22212239
}
22222240

2223-
// DATAMONGO-1491
2241+
// DATAMONGO-1491, GH-4443
22242242
@lombok.Data
22252243
@Builder
22262244
static class Item {
@@ -2229,6 +2247,7 @@ static class Item {
22292247
String itemId;
22302248
Integer quantity;
22312249
Long price;
2250+
List<String> tags = new ArrayList<>();
22322251
}
22332252

22342253
// DATAMONGO-1538

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

+20-1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
* @author Thomas Darimont
4545
* @author Christoph Strobl
4646
* @author Mark Paluch
47+
* @author Julia Lee
4748
*/
4849
public class AggregationUnitTests {
4950

@@ -607,7 +608,23 @@ void shouldNotConvertIncludeExcludeValuesForProjectOperation() {
607608
RelaxedTypeBasedAggregationOperationContext context = new RelaxedTypeBasedAggregationOperationContext(WithRetypedIdField.class, mappingContext,
608609
new QueryMapper(new MappingMongoConverter(NoOpDbRefResolver.INSTANCE, mappingContext)));
609610
Document document = project(WithRetypedIdField.class).toDocument(context);
610-
assertThat(document).isEqualTo(new Document("$project", new Document("_id", 1).append("renamed-field", 1)));
611+
assertThat(document).isEqualTo(new Document("$project", new Document("_id", 1).append("renamed-field", 1).append("entries", 1)));
612+
}
613+
614+
@Test // GH-4443
615+
void fieldsExposingContextShouldUseCustomFieldNameFromRelaxedRootContext() {
616+
617+
MongoMappingContext mappingContext = new MongoMappingContext();
618+
RelaxedTypeBasedAggregationOperationContext context = new RelaxedTypeBasedAggregationOperationContext(
619+
WithRetypedIdField.class, mappingContext,
620+
new QueryMapper(new MappingMongoConverter(NoOpDbRefResolver.INSTANCE, mappingContext)));
621+
622+
TypedAggregation<WithRetypedIdField> agg = newAggregation(WithRetypedIdField.class,
623+
unwind("entries"), match(where("foo").is("value 2")));
624+
List<Document> pipeline = agg.toPipeline(context);
625+
626+
Document fields = getAsDocument(pipeline.get(1), "$match");
627+
assertThat(fields.get("renamed-field")).isEqualTo("value 2");
611628
}
612629

613630
private Document extractPipelineElement(Document agg, int index, String operation) {
@@ -625,5 +642,7 @@ public class WithRetypedIdField {
625642
@org.springframework.data.mongodb.core.mapping.Field("renamed-field")
626643
private String foo;
627644

645+
private List<String> entries = new ArrayList<>();
646+
628647
}
629648
}

0 commit comments

Comments
 (0)