Browse Source

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
3.4.x
Julia Lee 2 years ago committed by Christoph Strobl
parent
commit
e1faf2652f
No known key found for this signature in database
GPG Key ID: 8CC1AB53391458C8
  1. 5
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ExposedFieldsAggregationOperationContext.java
  2. 23
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AggregationTests.java
  3. 21
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AggregationUnitTests.java

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

@ -67,6 +67,11 @@ class ExposedFieldsAggregationOperationContext implements AggregationOperationCo
* (non-Javadoc) * (non-Javadoc)
* @see org.springframework.data.mongodb.core.aggregation.AggregationOperationContext#getReference(org.springframework.data.mongodb.core.aggregation.ExposedFields.AvailableField) * @see org.springframework.data.mongodb.core.aggregation.AggregationOperationContext#getReference(org.springframework.data.mongodb.core.aggregation.ExposedFields.AvailableField)
*/ */
@Override
public Document getMappedObject(Document document) {
return rootContext.getMappedObject(document);
}
@Override @Override
public FieldReference getReference(Field field) { public FieldReference getReference(Field field) {

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

@ -87,6 +87,7 @@ import com.mongodb.client.MongoCollection;
* @author Maninder Singh * @author Maninder Singh
* @author Sergey Shcherbakov * @author Sergey Shcherbakov
* @author Minsu Kim * @author Minsu Kim
* @author Julia Lee
*/ */
@ExtendWith(MongoTemplateExtension.class) @ExtendWith(MongoTemplateExtension.class)
public class AggregationTests { public class AggregationTests {
@ -116,7 +117,7 @@ public class AggregationTests {
mongoTemplate.flush(Product.class, UserWithLikes.class, DATAMONGO753.class, Data.class, DATAMONGO788.class, mongoTemplate.flush(Product.class, UserWithLikes.class, DATAMONGO753.class, Data.class, DATAMONGO788.class,
User.class, Person.class, Reservation.class, Venue.class, MeterData.class, LineItem.class, InventoryItem.class, User.class, Person.class, Reservation.class, Venue.class, MeterData.class, LineItem.class, InventoryItem.class,
Sales.class, Sales2.class, Employee.class, Art.class, Venue.class); Sales.class, Sales2.class, Employee.class, Art.class, Venue.class, Item.class);
mongoTemplate.dropCollection(INPUT_COLLECTION); mongoTemplate.dropCollection(INPUT_COLLECTION);
mongoTemplate.dropCollection("personQueryTemp"); mongoTemplate.dropCollection("personQueryTemp");
@ -1962,6 +1963,23 @@ public class AggregationTests {
assertThat(aggregate.getMappedResults()).contains(widget); assertThat(aggregate.getMappedResults()).contains(widget);
} }
@Test // GH-4443
void shouldHonorFieldAliasesForFieldReferencesUsingFieldExposingOperation() {
Item item1 = Item.builder().itemId("1").tags(Arrays.asList("a", "b")).build();
Item item2 = Item.builder().itemId("1").tags(Arrays.asList("a", "c")).build();
mongoTemplate.insert(Arrays.asList(item1, item2), Item.class);
TypedAggregation<Item> aggregation = newAggregation(Item.class,
match(where("itemId").is("1")),
unwind("tags"),
match(where("itemId").is("1").and("tags").is("c")));
AggregationResults<Document> results = mongoTemplate.aggregate(aggregation, Document.class);
List<Document> mappedResults = results.getMappedResults();
assertThat(mappedResults).hasSize(1);
assertThat(mappedResults.get(0)).containsEntry("item_id", "1");
}
private void createUsersWithReferencedPersons() { private void createUsersWithReferencedPersons() {
mongoTemplate.dropCollection(User.class); mongoTemplate.dropCollection(User.class);
@ -2220,7 +2238,7 @@ public class AggregationTests {
List<Item> items; List<Item> items;
} }
// DATAMONGO-1491 // DATAMONGO-1491, GH-4443
@lombok.Data @lombok.Data
@Builder @Builder
static class Item { static class Item {
@ -2229,6 +2247,7 @@ public class AggregationTests {
String itemId; String itemId;
Integer quantity; Integer quantity;
Long price; Long price;
List<String> tags = new ArrayList<>();
} }
// DATAMONGO-1538 // DATAMONGO-1538

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

@ -44,6 +44,7 @@ import org.springframework.data.mongodb.core.query.Criteria;
* @author Thomas Darimont * @author Thomas Darimont
* @author Christoph Strobl * @author Christoph Strobl
* @author Mark Paluch * @author Mark Paluch
* @author Julia Lee
*/ */
public class AggregationUnitTests { public class AggregationUnitTests {
@ -607,7 +608,23 @@ public class AggregationUnitTests {
RelaxedTypeBasedAggregationOperationContext context = new RelaxedTypeBasedAggregationOperationContext(WithRetypedIdField.class, mappingContext, RelaxedTypeBasedAggregationOperationContext context = new RelaxedTypeBasedAggregationOperationContext(WithRetypedIdField.class, mappingContext,
new QueryMapper(new MappingMongoConverter(NoOpDbRefResolver.INSTANCE, mappingContext))); new QueryMapper(new MappingMongoConverter(NoOpDbRefResolver.INSTANCE, mappingContext)));
Document document = project(WithRetypedIdField.class).toDocument(context); Document document = project(WithRetypedIdField.class).toDocument(context);
assertThat(document).isEqualTo(new Document("$project", new Document("_id", 1).append("renamed-field", 1))); assertThat(document).isEqualTo(new Document("$project", new Document("_id", 1).append("renamed-field", 1).append("entries", 1)));
}
@Test // GH-4443
void fieldsExposingContextShouldUseCustomFieldNameFromRelaxedRootContext() {
MongoMappingContext mappingContext = new MongoMappingContext();
RelaxedTypeBasedAggregationOperationContext context = new RelaxedTypeBasedAggregationOperationContext(
WithRetypedIdField.class, mappingContext,
new QueryMapper(new MappingMongoConverter(NoOpDbRefResolver.INSTANCE, mappingContext)));
TypedAggregation<WithRetypedIdField> agg = newAggregation(WithRetypedIdField.class,
unwind("entries"), match(where("foo").is("value 2")));
List<Document> pipeline = agg.toPipeline(context);
Document fields = getAsDocument(pipeline.get(1), "$match");
assertThat(fields.get("renamed-field")).isEqualTo("value 2");
} }
private Document extractPipelineElement(Document agg, int index, String operation) { private Document extractPipelineElement(Document agg, int index, String operation) {
@ -625,5 +642,7 @@ public class AggregationUnitTests {
@org.springframework.data.mongodb.core.mapping.Field("renamed-field") @org.springframework.data.mongodb.core.mapping.Field("renamed-field")
private String foo; private String foo;
private List<String> entries = new ArrayList<>();
} }
} }

Loading…
Cancel
Save