Skip to content

Commit 62e528e

Browse files
committed
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
1 parent efb86de commit 62e528e

File tree

3 files changed

+54
-4
lines changed

3 files changed

+54
-4
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
@@ -119,7 +119,7 @@ private void cleanDb() {
119119

120120
mongoTemplate.flush(Product.class, UserWithLikes.class, DATAMONGO753.class, Data.class, DATAMONGO788.class,
121121
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);
122+
Sales.class, Sales2.class, Employee.class, Art.class, Venue.class, Item.class);
123123

124124
mongoTemplate.dropCollection(INPUT_COLLECTION);
125125
mongoTemplate.dropCollection("personQueryTemp");
@@ -2314,19 +2314,21 @@ public String toString() {
23142314
}
23152315
}
23162316

2317-
// DATAMONGO-1491
2317+
// DATAMONGO-1491, GH-4443
23182318
static class Item {
23192319

23202320
@org.springframework.data.mongodb.core.mapping.Field("item_id") //
23212321
String itemId;
23222322
Integer quantity;
23232323
Long price;
2324+
List<String> tags = new ArrayList<>();
23242325

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

23272328
this.itemId = itemId;
23282329
this.quantity = quantity;
23292330
this.price = price;
2331+
this.tags = tags;
23302332
}
23312333

23322334
public static ItemBuilder builder() {
@@ -2385,6 +2387,7 @@ public static class ItemBuilder {
23852387
private String itemId;
23862388
private Integer quantity;
23872389
private Long price;
2390+
private List<String> tags;
23882391

23892392
ItemBuilder() {}
23902393

@@ -2403,8 +2406,13 @@ public ItemBuilder price(Long price) {
24032406
return this;
24042407
}
24052408

2409+
public ItemBuilder tags(List<String> tags) {
2410+
this.tags = tags;
2411+
return this;
2412+
}
2413+
24062414
public Item build() {
2407-
return new Item(itemId, quantity, price);
2415+
return new Item(itemId, quantity, price, tags);
24082416
}
24092417

24102418
public String toString() {
@@ -2949,4 +2957,22 @@ public String toString() {
29492957
return "AggregationTests.UserRef(id=" + this.getId() + ", name=" + this.getName() + ")";
29502958
}
29512959
}
2960+
2961+
@Test // GH-4443
2962+
void shouldHonorFieldAliasesForFieldReferencesUsingFieldExposingOperation() {
2963+
2964+
Item item1 = Item.builder().itemId("1").tags(Arrays.asList("a", "b")).build();
2965+
Item item2 = Item.builder().itemId("1").tags(Arrays.asList("a", "c")).build();
2966+
mongoTemplate.insert(Arrays.asList(item1, item2), Item.class);
2967+
2968+
TypedAggregation<Item> aggregation = newAggregation(Item.class,
2969+
match(where("itemId").is("1")),
2970+
unwind("tags"),
2971+
match(where("itemId").is("1").and("tags").is("c")));
2972+
AggregationResults<Document> results = mongoTemplate.aggregate(aggregation, Document.class);
2973+
List<Document> mappedResults = results.getMappedResults();
2974+
assertThat(mappedResults).hasSize(1);
2975+
assertThat(mappedResults.get(0)).containsEntry("item_id", "1");
2976+
}
2977+
29522978
}

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

+19
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.springframework.data.annotation.Id;
3232
import org.springframework.data.domain.Sort;
3333
import org.springframework.data.domain.Sort.Direction;
34+
import org.springframework.data.mongodb.core.DocumentTestUtils;
3435
import org.springframework.data.mongodb.core.aggregation.ConditionalOperators.Cond;
3536
import org.springframework.data.mongodb.core.aggregation.ProjectionOperationUnitTests.BookWithFieldAnnotation;
3637
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
@@ -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)