The Agg Tag

JETT's integration with the jAgg project allows the use of the "agg" tag, which performs aggregate operations on a List of items, yielding aggregate results that can be populated in the resultant spreadsheet. The "agg" tag requires a body.

Attributes

  • The "agg" tag supports all base tag attributes.
  • items: List Required. This is the List of items to aggregate.
  • aggs: String Required. This is a list of aggregator specification strings, delimited by semicolons, e.g. "Avg(price);Sum(quantity)". These represent aggregate operations to perform on the list of values. A property may be nested, e.g. "Avg(stock.price)".
  • aggsVar: String Optional. If given, this is the name under which the array of AggregateFunction objects will be published in the beans map. This new bean can only be referenced from within the Block defined by the tag.
  • valuesVar: String Required. This is the name under which the aggregate results will be published in the beans map. This new bean can only be referenced from within the Block defined by the tag.
  • groupBy: String Optional. This is a semicolon-separated list of property names that represents categories under which to group aggregate results. Default: no categories. If this is specified, then there may be multiple rows of aggregate results to display. A property may be nested, e.g. "item.elementB.displayName".
  • parallel: int Optional. Specify a degree of parallelism directly to the jAgg library. Default: 1
  • useMsd: boolean Optional. Specify whether to use Multiset Discrimination instead of sorting to organize the list for aggregation operations. This has the side effect that items returned may not be in sorted order. jAgg falls back on sorting if Multiset Discrimination fails. This defaults to false, don't use Multiset Discrimination (use sorting).
  • rollup: int[] Optional. Specifies which properties are to be involved in a rollup calculation, with 0-based integer indexes into the original List of properties (groupBy). This can be specified in many ways:
    • A JEXL array literal: rollup="${[0, 1]}"
    • A bean: rollup="${intArray}"
    • A string (delimited by semicolons): rollup="0;1"
  • rollups: int[][] Optional. Specifies which sets of properties are to be involved in multiple rollups, with 0-based integer indexes into the original List of properties (groupBy). This can be specified in many ways:
    • A JEXL 2D array literal: rollups="${[[0, 1], [2]]}"
    • A bean: rollups="${int2dArray}"
    • A string (delimited by semicolons and commas): rollups="0,1;2"
  • cube: int[] Optional. Specifies which properties are to be involved in a data cube calculation, with 0-based integer indexes into the original List of properties (groupBy). This can be specified in many ways:
    • A JEXL array literal: cube="${[0, 1, 2]}"
    • A bean: cube="${intArray}"
    • A string (delimited by semicolons): cube="0;1;2"
  • groupingSets: int[][] Optional. Specifies exactly which sets of properties are to be involved in grouping set operations, with 0-based integer indexes into the original List of properties (groupBy). Specify an empty array to include grand totals. This can be specified in many ways:
    • A JEXL 2D array literal: groupingSets="${[[0, 1], [2], []]}"
    • A bean: groupingSets="${int2dArray}"
    • A string (delimited by semicolons and commas): groupingSets="0,1;2;"

The AggregateFunctions specified in the "aggs" attribute may be an AggregateFunction, either built-in to the jAgg library, or custom built by the developer.

Usually, a forEach tag is used inside the body of the "agg" tag to display the aggregate results.

Example

A List of Employees is available in the beans map.

  • Robert Stack, salary $1000, title "Data Structures Programmer", isManager true
  • Suzie Queue, salary $900, title "Data Structures Programmer"
  • Elmer Fudd, salary $800, title "Cartoon Character", catch phrase "I'm hunting wabbits! Huh-uh-uh!"
  • Bugs Bunny, salary $1500, title "Cartoon Character", isManager true, catch phrase "Ah, what's up Doc?"
Title Employee Count Total Salary Average Salary
<jt:agg items="${employees}" aggs="Count(*);Sum(salary);Avg(salary)" aggsVar="aggs" valuesVar="results" groupBy="title"><jt:forEach items="${results}" var="result">{result.object.title} ${result.getAggregateValue(aggs[0])} ${result.getAggregateValue(aggs[1])} ${result.getAggregateValue(aggs[2])}</jt:forEach></jt:agg>

One can refer to aggregate values by passing in the indexed AggregateFunction or by passing the index itself into the "getAggregateValue" method. Alternatively, the template above could pass the index itself:

Title Employee Count Total Salary Average Salary
<jt:agg items="${employees}" aggs="Count(*);Sum(salary);Avg(salary)" aggsVar="aggs" valuesVar="results" groupBy="title"><jt:forEach items="${results}" var="result">{result.object.title} ${result.getAggregateValue(0)} ${result.getAggregateValue(1)} ${result.getAggregateValue(2)}</jt:forEach></jt:agg>

...Either way, it gets transformed into...

Title Employee Count Total Salary Average Salary
Data Structures Programmer 2 $2300.00 $1150.00
Cartoon Character 2 $1900.00 $950.00

Rollup Example

This template specifies a rollup operation. Subtotals are calculated beginning with the rightmost property specified, and ending with the leftmost property specified (grand totals). Notice how the "isGrouping" method is used to determine whether the property value represents "All Values". Also, notice that specifying rollup="${[0,1]}" is equivalent to groupingSets="${[[0, 1], [0], []]}".

Is A Manager Title Total Salary
<jt:agg items="${employees}" aggs="Sum(salary)" valuesVar="values" groupBy="isManager();title" rollup="${[0,1]}"> <jt:forEach items="${values}" var="value" orderBy="getPropertyValue(0);getPropertyValue(1)"> ${value.isGrouping(0) ? 'All Values' : value.getPropertyValue(0)} ${value.isGrouping(1) ? 'All Values' : value.getPropertyValue(1)} ${value.getAggregateValue(0])}</jt:forEach></jt:agg>

Gets transformed into...

Is A Manager Title Total Salary
FALSE Cartoon Character $800.00
FALSE Data Structures Programmer $900.00
FALSE All Values $1,700.00
TRUE Cartoon Character $1,500.00
TRUE Data Structures Programmer $1,000.00
TRUE All Values $2,500.00
All Values All Values $4,200.00

Rollups Example

This template specifies multiple rollup operations. Each rollup combination is itself rolled up with the other rollup combinations. Notice that specifying rollups="${[[1], [2]]}" is equivalent to groupingSets="${[[0], [0, 1], [0, 2], [0, 1, 2]]}".

Is A Manager Title Catch Phrase Total Salary
<jt:agg items="${employees}" aggs="Sum(salary)" valuesVar="values" groupBy="isManager();title;catchPhrase" rollups="${[[1], [2]]}"><jt:forEach items="${values}" var="value" orderBy="getPropertyValue(0);getPropertyValue(1);getPropertyValue(2)"> ${value.isGrouping(0) ? 'All Values' : value.getPropertyValue(0)} ${value.isGrouping(1) ? 'All Values' : value.getPropertyValue(1)} ${value.isGrouping(2) ? 'All Values' : value.getPropertyValue(2)} ${value.getAggregateValue(0)}</jt:forEach></jt:agg>

Gets transformed into...

Is A Manager Title Catch Phrase Total Salary
FALSE Cartoon Character I'm hunting wabbits! Huh-uh-uh! $800.00
FALSE Cartoon Character All Values $800.00
FALSE Data Structures Programmer   $900.00
FALSE Data Structures Programmer All Values $900.00
FALSE All Values I'm hunting wabbits! Huh-uh-uh! $800.00
FALSE All Values   $900.00
FALSE All Values All Values $1,700.00
TRUE Cartoon Character Ah, what's up doc? $1,500.00
TRUE Cartoon Character All Values $1,500.00
TRUE Data Structures Programmer   $1,000.00
TRUE Data Structures Programmer All Values $1,000.00
TRUE All Values Ah, what's up doc? $1,500.00
TRUE All Values   $1,000.00
TRUE All Values All Values $2,500.00

Cube Example

This template specifies a data cube operation. Each property combination is computed from all properties specified. Notice that specifying cube="${[0, 1, 2]}" is equivalent to groupingSets="${[[], [0], [1], [2], [0, 1], [0, 2], [1, 2], [0, 1, 2]]}".

Is A Manager Title Catch Phrase Total Salary
<jt:agg items="${employees}" aggs="Sum(salary)" valuesVar="values" groupBy="isManager();title;catchPhrase" cube="${[0, 1, 2]}"><jt:forEach items="${values}" var="value" orderBy="getPropertyValue(0);getPropertyValue(1);getPropertyValue(2)"> ${value.isGrouping(0) ? 'All Values' : value.getPropertyValue(0)} ${value.isGrouping(1) ? 'All Values' : value.getPropertyValue(1)} ${value.isGrouping(2) ? 'All Values' : value.getPropertyValue(2)} ${value.getAggregateValue(0)}</jt:forEach></jt:agg>

Gets transformed into...

Is A Manager Title Catch Phrase Total Salary
FALSE Cartoon Character I'm hunting wabbits! Huh-uh-uh! $800.00
FALSE Cartoon Character All Values $800.00
FALSE Data Structures Programmer   $900.00
FALSE Data Structures Programmer All Values $900.00
FALSE All Values I'm hunting wabbits! Huh-uh-uh! $800.00
FALSE All Values   $900.00
FALSE All Values All Values $1,700.00
TRUE Cartoon Character Ah, what's up doc? $1,500.00
TRUE Cartoon Character All Values $1,500.00
TRUE Data Structures Programmer   $1,000.00
TRUE Data Structures Programmer All Values $1,000.00
TRUE All Values Ah, what's up doc? $1,500.00
TRUE All Values   $1,000.00
TRUE All Values All Values $2,500.00
All Values Cartoon Character Ah, what's up doc? $1,500.00
All Values Cartoon Character I'm hunting wabbits! Huh-uh-uh! $800.00
All Values Cartoon Character All Values $2,300.00
All Values Data Structures Programmer   $1,900.00
All Values Data Structures Programmer All Values $1,900.00
All Values All Values Ah, what's up doc? $1,500.00
All Values All Values I'm hunting wabbits! Huh-uh-uh! $800.00
All Values All Values   $1,900.00
All Values All Values All Values $4,200.00

Grouping Sets Example

This template contains super aggregate operations representing specific grouping sets. Such grouping sets do not necessarily have anything to do with each other.

Is A Manager Title Catch Phrase Total Salary
<jt:agg items="${employees}" aggs="Sum(salary)" valuesVar="values" groupBy="isManager();title;catchPhrase" groupingSets="${[[0], [1, 2]]}"><jt:forEach items="${values}" var="value"> ${value.isGrouping(0) ? 'All Values' : value.getPropertyValue(0)} ${value.isGrouping(1) ? 'All Values' : value.getPropertyValue(1)} ${value.isGrouping(2) ? 'All Values' : value.getPropertyValue(2)} ${value.getAggregateValue(0)}</jt:forEach></jt:agg>

Gets transformed into...

Is A Manager Title Catch Phrase Total Salary
FALSE All Values All Values $1,700.00
TRUE All Values All Values $2,500.00
All Values Cartoon Character Ah, what's up Doc? $1,500.00
All Values Cartoon Character I'm hunting wabbits! Huh-uh-uh! $800.00
All Values Data Structures Programmer   $1,900.00

Notice that the first two data rows represent the grouping set "[0]" and the last three data rows represent the grouping set "[1, 2]".