Skip to content

Commit 9b82ede

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 e198637 commit 9b82ede

File tree

3 files changed

+55
-5
lines changed

3 files changed

+55
-5
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
@@ -60,6 +60,11 @@ public Document getMappedObject(Document document, @Nullable Class<?> type) {
6060
return rootContext.getMappedObject(document, type);
6161
}
6262

63+
@Override
64+
public Document getMappedObject(Document document) {
65+
return rootContext.getMappedObject(document);
66+
}
67+
6368
@Override
6469
public FieldReference getReference(Field field) {
6570

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

+30-4
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@
9191
* @author Sergey Shcherbakov
9292
* @author Minsu Kim
9393
* @author Sangyong Choi
94+
* @author Julia Lee
9495
*/
9596
@ExtendWith(MongoTemplateExtension.class)
9697
public class AggregationTests {
@@ -119,7 +120,7 @@ private void cleanDb() {
119120

120121
mongoTemplate.flush(Product.class, UserWithLikes.class, DATAMONGO753.class, Data.class, DATAMONGO788.class,
121122
User.class, Person.class, Reservation.class, Venue.class, MeterData.class, LineItem.class, InventoryItem.class,
122-
Sales.class, Sales2.class, Employee.class, Art.class, Venue.class);
123+
Sales.class, Sales2.class, Employee.class, Art.class, Venue.class, Item.class);
123124

124125
mongoTemplate.dropCollection(INPUT_COLLECTION);
125126
mongoTemplate.dropCollection("personQueryTemp");
@@ -1992,6 +1993,23 @@ void considersMongoIdWithinTypedCollections() {
19921993
assertThat(aggregate.getMappedResults()).contains(widget);
19931994
}
19941995

1996+
@Test // GH-4443
1997+
void shouldHonorFieldAliasesForFieldReferencesUsingFieldExposingOperation() {
1998+
1999+
Item item1 = Item.builder().itemId("1").tags(Arrays.asList("a", "b")).build();
2000+
Item item2 = Item.builder().itemId("1").tags(Arrays.asList("a", "c")).build();
2001+
mongoTemplate.insert(Arrays.asList(item1, item2), Item.class);
2002+
2003+
TypedAggregation<Item> aggregation = newAggregation(Item.class,
2004+
match(where("itemId").is("1")),
2005+
unwind("tags"),
2006+
match(where("itemId").is("1").and("tags").is("c")));
2007+
AggregationResults<Document> results = mongoTemplate.aggregate(aggregation, Document.class);
2008+
List<Document> mappedResults = results.getMappedResults();
2009+
assertThat(mappedResults).hasSize(1);
2010+
assertThat(mappedResults.get(0)).containsEntry("item_id", "1");
2011+
}
2012+
19952013
private void createUsersWithReferencedPersons() {
19962014

19972015
mongoTemplate.dropCollection(User.class);
@@ -2314,19 +2332,21 @@ public String toString() {
23142332
}
23152333
}
23162334

2317-
// DATAMONGO-1491
2335+
// DATAMONGO-1491, GH-4443
23182336
static class Item {
23192337

23202338
@org.springframework.data.mongodb.core.mapping.Field("item_id") //
23212339
String itemId;
23222340
Integer quantity;
23232341
Long price;
2342+
List<String> tags = new ArrayList<>();
23242343

2325-
Item(String itemId, Integer quantity, Long price) {
2344+
Item(String itemId, Integer quantity, Long price, List<String> tags) {
23262345

23272346
this.itemId = itemId;
23282347
this.quantity = quantity;
23292348
this.price = price;
2349+
this.tags = tags;
23302350
}
23312351

23322352
public static ItemBuilder builder() {
@@ -2385,6 +2405,7 @@ public static class ItemBuilder {
23852405
private String itemId;
23862406
private Integer quantity;
23872407
private Long price;
2408+
private List<String> tags;
23882409

23892410
ItemBuilder() {}
23902411

@@ -2403,8 +2424,13 @@ public ItemBuilder price(Long price) {
24032424
return this;
24042425
}
24052426

2427+
public ItemBuilder tags(List<String> tags) {
2428+
this.tags = tags;
2429+
return this;
2430+
}
2431+
24062432
public Item build() {
2407-
return new Item(itemId, quantity, price);
2433+
return new Item(itemId, quantity, price, tags);
24082434
}
24092435

24102436
public String toString() {

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

+20-1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
* @author Thomas Darimont
5050
* @author Christoph Strobl
5151
* @author Mark Paluch
52+
* @author Julia Lee
5253
*/
5354
public class AggregationUnitTests {
5455

@@ -612,7 +613,7 @@ void shouldNotConvertIncludeExcludeValuesForProjectOperation() {
612613
WithRetypedIdField.class, mappingContext,
613614
new QueryMapper(new MappingMongoConverter(NoOpDbRefResolver.INSTANCE, mappingContext)));
614615
Document document = project(WithRetypedIdField.class).toDocument(context);
615-
assertThat(document).isEqualTo(new Document("$project", new Document("_id", 1).append("renamed-field", 1)));
616+
assertThat(document).isEqualTo(new Document("$project", new Document("_id", 1).append("renamed-field", 1).append("entries", 1)));
616617
}
617618

618619
@Test // GH-4038
@@ -653,6 +654,22 @@ void inheritedFieldsExposingContextShouldNotFailOnUnknownFieldReferenceForRelaxe
653654
assertThat(documents.get(2)).isEqualTo("{ $sort : { 'serial_number' : -1, 'label_name' : -1 } }");
654655
}
655656

657+
@Test // GH-4443
658+
void fieldsExposingContextShouldUseCustomFieldNameFromRelaxedRootContext() {
659+
660+
MongoMappingContext mappingContext = new MongoMappingContext();
661+
RelaxedTypeBasedAggregationOperationContext context = new RelaxedTypeBasedAggregationOperationContext(
662+
WithRetypedIdField.class, mappingContext,
663+
new QueryMapper(new MappingMongoConverter(NoOpDbRefResolver.INSTANCE, mappingContext)));
664+
665+
TypedAggregation<WithRetypedIdField> agg = newAggregation(WithRetypedIdField.class,
666+
unwind("entries"), match(where("foo").is("value 2")));
667+
List<Document> pipeline = agg.toPipeline(context);
668+
669+
Document fields = getAsDocument(pipeline.get(1), "$match");
670+
assertThat(fields.get("renamed-field")).isEqualTo("value 2");
671+
}
672+
656673
private Document extractPipelineElement(Document agg, int index, String operation) {
657674

658675
List<Document> pipeline = (List<Document>) agg.get("pipeline");
@@ -672,5 +689,7 @@ public class WithRetypedIdField {
672689

673690
@org.springframework.data.mongodb.core.mapping.Field("renamed-field") private String foo;
674691

692+
private List<String> entries = new ArrayList<>();
693+
675694
}
676695
}

0 commit comments

Comments
 (0)