diff --git a/mongodb/aggregation/src/main/java/example/springdata/mongodb/aggregation/OrderRepository.java b/mongodb/aggregation/src/main/java/example/springdata/mongodb/aggregation/OrderRepository.java index a321571f..786439b5 100644 --- a/mongodb/aggregation/src/main/java/example/springdata/mongodb/aggregation/OrderRepository.java +++ b/mongodb/aggregation/src/main/java/example/springdata/mongodb/aggregation/OrderRepository.java @@ -22,7 +22,8 @@ import org.springframework.data.mongodb.repository.Aggregation; import org.springframework.data.repository.CrudRepository; /** - * A repository interface assembling CRUD functionality as well as the API to invoke the methods implemented manually. + * A repository interface assembling CRUD functionality as well as the API to + * invoke the methods implemented manually. * * @author Thomas Darimont * @author Oliver Gierke @@ -35,4 +36,11 @@ public interface OrderRepository extends CrudRepository, OrderRep @Aggregation(pipeline = { "{ $match : { customerId : ?0 } }", "{ $count : total }" }) Long totalOrdersForCustomer(String customerId); + + @Aggregation(pipeline = { "{ $match : { id : ?0 } }", "{ $unwind : { path : '$items' } }", + "{ $project : { id : 1 , customerId : 1 , items : 1 , lineTotal : { $multiply: [ '$items.price' , '$items.quantity' ] } } }", + "{ $group : { '_id' : '$_id' , 'netAmount' : { $sum : '$lineTotal' } , 'items' : { $addToSet : '$items' } } }", + "{ $project : { 'orderId' : '$_id' , 'items' : 1 , 'netAmount' : 1 , 'taxAmount' : { $multiply: [ '$netAmount' , 0.19 ] } , 'totalAmount' : { $multiply: [ '$netAmount' , 1.19 ] } } }" }) + Invoice getInvoiceForOrderDeclarative(String orderId); + } diff --git a/mongodb/aggregation/src/test/java/example/springdata/mongodb/aggregation/OrderRepositoryIntegrationTests.java b/mongodb/aggregation/src/test/java/example/springdata/mongodb/aggregation/OrderRepositoryIntegrationTests.java index 28c5d366..74b5262e 100644 --- a/mongodb/aggregation/src/test/java/example/springdata/mongodb/aggregation/OrderRepositoryIntegrationTests.java +++ b/mongodb/aggregation/src/test/java/example/springdata/mongodb/aggregation/OrderRepositoryIntegrationTests.java @@ -51,7 +51,7 @@ public class OrderRepositoryIntegrationTests { } @Test - public void createsInvoiceViaAggregation() { + public void createsInvoiceViaAggregationProgrammatic() { Order order = new Order("c42", new Date()).// addItem(product1).addItem(product2).addItem(product3); @@ -65,6 +65,22 @@ public class OrderRepositoryIntegrationTests { assertThat(invoice.getTaxAmount()).isCloseTo(1.577D, offset(0.00001)); assertThat(invoice.getTotalAmount()).isCloseTo(9.877, offset(0.00001)); } + + @Test + public void createsInvoiceViaAggregationDeclarative() { + + Order order = new Order("c42", new Date()).// + addItem(product1).addItem(product2).addItem(product3); + order = repository.save(order); + + Invoice invoice = repository.getInvoiceForOrderDeclarative(order.getId()); + + assertThat(invoice).isNotNull(); + assertThat(invoice.getOrderId()).isEqualTo(order.getId()); + assertThat(invoice.getNetAmount()).isCloseTo(8.3D, offset(0.00001)); + assertThat(invoice.getTaxAmount()).isCloseTo(1.577D, offset(0.00001)); + assertThat(invoice.getTotalAmount()).isCloseTo(9.877, offset(0.00001)); + } @Test public void declarativeAggregationWithSort() { @@ -94,4 +110,5 @@ public class OrderRepositoryIntegrationTests { assertThat(repository.totalOrdersForCustomer("c42")).isEqualTo(3); } + }