Obtaining and Organizing Query Results
Queries return a Results object that contains a list of objects of class Result. Each element in the cache that a query finds is represented as a Result object. For example, if a query finds 350 elements, there will be 350 Result objects. However, if no keys or attributes are included but aggregators are included, there is exactly one Result present.
A Result object can contain:
The Element key - when
includeKeys() is added to the query,
The Element value - when
includeValues() is added to the query,
Predefined attribute(s) extracted from an Element value - when
includeAttribute(...) is added to the query. To access an attribute from a Result, use
getAttribute(Attribute<T> attribute).
Aggregator results - Aggregator results are summaries computed for the search. They are available through Result.getAggregatorResults, which returns a list of Aggregators in the same order in which they were used in the query.
Aggregators
Aggregators are added with query.includeAggregator(\<attribute\>.\<aggregator\>). For example, to find the sum of the age attribute:
query.includeAggregator(age.sum());
For a complete list of aggregators, see Aggregators in the Ehcache Javadoc at
http://www.ehcache.org/apidocs/2.10.1/.
Ordering Results
Query results can be ordered in ascending or descending order by adding an addOrderBy clause to the query. This clause takes as parameters the attribute to order by and the ordering direction. For example, to order the results by ages in ascending order:
query.addOrderBy(age, Direction.ASCENDING);
Grouping Results
Query query results can be grouped similarly to using an SQL GROUP BY statement. The GroupBy feature provides the option to group results according to specified attributes. You can add an addGroupBy clause to the query, which takes as parameters the attributes to group by. For example, you can group results by department and location:
Query q = cache.createQuery();
Attribute<String> dept = cache.getSearchAttribute("dept");
Attribute<String> loc = cache.getSearchAttribute("location");
q.includeAttribute(dept);
q.includeAttribute(loc);
q.addCriteria(cache.getSearchAttribute("salary").gt(100000));
q.includeAggregator(Aggregators.count());
q.addGroupBy(dept, loc);
The GroupBy clause groups the results from includeAttribute( ) and allows aggregate functions to be performed on the grouped attributes. To retrieve the attributes that are associated with the aggregator results, you can use:
String dept = singleResult.getAttribute(dept);
String loc = singleResult.getAttribute(loc);
GroupBy Rules
Grouping query results adds another step to the query. First, results are returned, and second the results are grouped. Note the following rules and considerations:
In a query with a GroupBy clause, any attribute specified using includeAttribute( ) should also be included in the GroupBy clause.
Special KEY or VALUE attributes cannot be used in a GroupBy clause. This means that includeKeys( ) and includeValues( ) cannot be used in a query that has a GroupBy clause.
Adding a GroupBy clause to a query changes the semantics of any aggregators passed in, so that they apply only within each group.
As long as there is at least one aggregation function specified in a query, the grouped attributes are not required to be included in the result set, but they are typically requested anyway to make result processing easier.
An addCriteria clause applies to all results prior to grouping.
If OrderBy is used with GroupBy, the ordering attributes are limited to those listed in the GroupBy clause.
Limiting the Size of Results
By default, a query can return an unlimited number of results. For example, the following query will return all keys in the cache.
Query query = cache.createQuery();
query.includeKeys();
query.execute();
If too many results are returned, it could cause an OutOfMemoryError The maxResults clause is used to limit the size of the results. For example, to limit the above query to the first 100 elements found:
Query query = cache.createQuery();
query.includeKeys();
query.maxResults(100);
query.execute();
Note: When maxResults is used with GroupBy, it limits the number of groups.
When you are done with the results, call the discard( ) method to free up resources.
For additional information about managing large result sets, see the topics that relate to pagination in
Best Practices for Optimizing Searches.
Interrogating Results
To determine what a query returned, use one of the interrogation methods on Results.:
hasKeys( )
hasValues( )
hasAttributes( )
hasAggregators( )