Files
spring-data-examples/mongodb/aggregation
Christoph Strobl 84ca79d97f #523 - Add example for declarative MongoDB aggregations.
Original pull request: #526.
closes: #523
2019-08-16 14:31:11 +02:00
..
2019-03-20 10:10:59 -05:00

Spring Data MongoDB - Aggregations

This project contains usage samples for using MongoDB Aggregations showing both the programmatic and declarative approach for integrating an Aggregation Pipeline into the repository lay.

Programmatic

The programmatic approach uses a custom repository implementation along with the Aggregation Framework.

class OrderRepositoryImpl implements OrderRepositoryCustom {

	private MongoOperations operations;
	
	// ...

	@Override
	public Invoice getInvoiceFor(Order order) {

		AggregationResults<Invoice> results = operations.aggregate(newAggregation(Order.class, 
			match(where("id").is(order.getId())), 
			unwind("items"), 
			project("id", "customerId", "items") 
				.andExpression("'$items.price' * '$items.quantity'").as("lineTotal"), 
			group("id") 
				.sum("lineTotal").as("netAmount") 
				.addToSet("items").as("items"), 
			project("id", "items", "netAmount") 
				.and("orderId").previousOperation() 
				.andExpression("netAmount * [0]", taxRate).as("taxAmount") 
				.andExpression("netAmount * (1 + [0])", taxRate).as("totalAmount") 
		), Invoice.class);

		return results.getUniqueMappedResult();
	}
}

Declarative

The declarative approach allows to define an Aggregation Pipeline via the @Aggregation annotation.

public interface OrderRepository extends CrudRepository<Order, String>, OrderRepositoryCustom {

	@Aggregation("{ $group : { _id : $customerId, total : { $sum : 1 } } }")
	List<OrdersPerCustomer> totalOrdersPerCustomer(Sort sort);

	@Aggregation(pipeline = { "{ $match : { customerId : ?0 } }", "{ $count : total }" })
	Long totalOrdersForCustomer(String customerId);
}