see on GitHub

Session : Querying : How to perform dynamic aggregation?

Dynamic aggregation can be performed using AggregateBy method. Internally such aggregation is an extended faceted search.

Syntax

DynamicAggregationQuery<TResult> AggregateBy<TResult>(
	this IQueryable<TResult> queryable,
	string path,
	string displayName = null) { ... }

DynamicAggregationQuery<TResult> AggregateBy<TResult>(
	this IQueryable<TResult> queryable,
	Expression<Func<TResult, object>> path) { ... }

DynamicAggregationQuery<TResult> AggregateBy<TResult>(
	this IQueryable<TResult> queryable,
	Expression<Func<TResult, object>> path,
	string displayName) { ... }

Parameters
path string or Expression<Func<TResult>> Path (or expression from which path will be extracted) to field on which aggregation will be performed.
displayName string User defined friendly name for aggregation. If null, field name will be used.
Return Value
DynamicAggregationQuery<TResult> Query containing aggregation methods.

Example I - summing

// sum up all order prices
// for each customer
// where price is higher than 500
FacetResults aggregationResults = session.Query<Order>("Orders/All")
	.Where(x => x.TotalPrice > 500)
	.AggregateBy(x => x.CustomerId)
		.SumOn(x => x.TotalPrice)
	.ToList();

FacetResult customerAggregation = aggregationResults.Results["CustomerId"];
double? sum = customerAggregation.Values[0].Sum;

Example II - counting

// count all orders
// for each customer
// where price is higher than 500
FacetResults aggregationResults = session.Query<Order>("Orders/All")
	.Where(x => x.TotalPrice > 500)
	.AggregateBy(x => x.CustomerId)
		.CountOn(x => x.TotalPrice)
	.ToList();

FacetResult customerAggregation = aggregationResults.Results["CustomerId"];
int? count = customerAggregation.Values[0].Count;

Example III - average

// count price average for orders
// for each customer
// where price is higher than 500
FacetResults aggregationResults = session.Query<Order>("Orders/All")
	.Where(x => x.TotalPrice > 500)
	.AggregateBy(x => x.CustomerId)
		.AverageOn(x => x.TotalPrice)
	.ToList();

FacetResult customerAggregation = aggregationResults.Results["CustomerId"];
double? average = customerAggregation.Values[0].Average;

Example IV - maximum and minimum

// count max and min price for orders
// for each customer
// where price is higher than 500
FacetResults aggregationResults = session.Query<Order>("Orders/All")
	.Where(x => x.TotalPrice > 500)
	.AggregateBy(x => x.CustomerId)
		.MinOn(x => x.TotalPrice)
		.MaxOn(x => x.TotalPrice)
	.ToList();

FacetResult customerAggregation = aggregationResults.Results["CustomerId"];
double? min = customerAggregation.Values[0].Min;
double? max = customerAggregation.Values[0].Max;

Example V - adding ranges

FacetResults aggregationResults = session.Query<Order>("Orders/All")
	.AggregateBy(x => x.CustomerId)
		.AddRanges(x => x.TotalPrice < 100)
		.AddRanges(x => x.TotalPrice >= 100 && x.TotalPrice < 500)
		.AddRanges(x => x.TotalPrice >= 500 && x.TotalPrice < 1000)
		.AddRanges(x => x.TotalPrice >= 1000)
	.ToList();

FacetResult customerAggregation = aggregationResults.Results["CustomerId"];
FacetValue range1 = customerAggregation.Values.First(x => x.Range == "[NULL to Dx100]");
FacetValue range2 = customerAggregation.Values.First(x => x.Range == "{Dx100 to Dx500]");
FacetValue range3 = customerAggregation.Values.First(x => x.Range == "{Dx500 to Dx1000]");
FacetValue range4 = customerAggregation.Values.First(x => x.Range == "{Dx1000 to NULL]");

Example VI - multiple aggregations

// sum up all order prices
// for each customer
// count price average for all orders
// for each company
FacetResults aggregationResults = session.Query<Order>("Orders/All")
	.AggregateBy(x => x.CustomerId)
		.SumOn(x => x.TotalPrice)
	.AndAggregateOn(x => x.CompanyId)
		.AverageOn(x => x.TotalPrice)
	.ToList();

FacetResult customerAggregation = aggregationResults.Results["CustomerId"];
FacetResult companyAggregation = aggregationResults.Results["CompanyId"];

double? sum = customerAggregation.Values[0].Sum;
double? average = companyAggregation.Values[0].Average;