Skip Headers
Oracle® Coherence Tutorial for Oracle Coherence
Release 3.6

Part Number E15831-01
Go to Documentation Home
Home
Go to Book List
Book List
Go to Table of Contents
Contents
Go to Index
Index
Go to Feedback page
Contact Us

Go to previous page
Previous
Go to next page
Next
View PDF

6 Simplifying Cache Calls and Aggregations

In the previous chapter you created a file, QueryExample.java, that used a variety of filters, such as AlwaysFilter, LikeFilter, and EqualsFilter, to pull and aggregate information from the cache. The file also created indexes on the data by employing a variety of specialized ValueExtractors: ChainedExtractors, KeyExtractors, and ReflectionExtractors. The result was some very verbose Java statements. These statements can be simplified by using the QueryHelper API.

This chapter contains the following sections:

6.1 Introduction

To simplify filter and extractor statements, and the way in which you interact with the Coherence caches, the current release provides the QueryHelper API. QueryHelper (com.tangosol.util.QueryHelper) is a utility class that provides a set of createFilter and createExtractor factory methods that can build instances of Filter and ValueExtractor. The methods in the class accept a String that specifies the creation of rich Filters in a format that should be familiar to anyone that understands SQL WHERE clauses.

For example, the following statement uses createFilter(String s) to create a filter. It constructs a filter for employees who live in Massachusetts but work in another state.

..
QueryHelper.createFilter("homeAddress.state = 'MA' and workAddress.state !='MA'")
...

This statement is more simple than the equivalent filter/extractor statement using the Coherence API:

new AndFilter(new EqualsFilter("getHomeAddress.getState", "MA"), 
      new NotEqualsFilter("getWorkAddress.getState", "MA")) 

For more information, see the Javadoc for the QueryHelper API. For information on the syntax of the WHERE clause within the Coherence Query Language, see Using Coherence Query Language in the Developer's Guide for Oracle Coherence.

6.2 Simplifying the Query Example

This section describes how you can simplify the indexes, cache calls, and aggregations in the QueryExample.java file that you created in the previous chapter.

  1. Import the QueryHelper API as a static class.

    import static com.tangosol.util.QueryHelper.*;
    
  2. Comment out the imports for the ChainedExtractor, KeyExtractor, and ReflectionExtractor classes.

  3. Comment out the imports for the AlwaysFilter, AndFilter, EqualsFilter, GreaterFilter, LikeFilter, and NotEqualsFilter classes.

  4. In the cache.addIndex statements, replace instances of ReflectionExtractor with createExtractor from the QueryHelper API.

    Table 6-1 lists the ReflectionExtractor instances and their createExtractor equivalents.

    Table 6-1 ReflectionExtractors and their Equivalent createExtractor Statements

    Replace this ReflectionExtractor statement... With the equivalent createExtractor statement

    cache.addIndex(new ReflectionExtractor("getAge"), true, null);

    cache.addIndex(createExtractor("age"), true, null);

    cache.addIndex(new ChainedExtractor(reflectAddrHome, new ReflectionExtractor("getState")), true, null);

    cache.addIndex(createExtractor("homeAddress.state"), false, null);

    cache.addIndex(new ChainedExtractor(new ReflectionExtractor("getWorkAddress"), new ReflectionExtractor("getState")), true, null);

    cache.addIndex(createExtractor("workAddress.state"),false, null);

    cache.addIndex(new ChainedExtractor(reflectAddrHome, new ReflectionExtractor("getCity")), true, null);

    cache.addIndex(createExtractor("homeAddress.city"), true, null);


  5. Replace the calls to the *Filter methods in the setResults statements with calls to createFilter with the appropriate Coherence Query Language.

    Table 6-2 lists the *Filter instances and their createFilter equivalents.

    Table 6-2 *Filter Statements and their Equivalent createFilter Statements in Queries

    Replace this *Filter statement... With the equivalent createFilter statement

    Set setResults = cache.entrySet(new EqualsFilter("getHomeAddress.getState", "MA"));

    Set setResults = cache.entrySet(createFilter("homeAddress.state = 'MA'"));

    Set setResults = cache.entrySet(new AndFilter(new EqualsFilter("getHomeAddress.getState", "MA"), new NotEqualsFilter("getWorkAddress.getState", "MA")));

    setResults = cache.entrySet( createFilter("homeAddress.state is 'MA' and workAddress is not 'MA'"));

    Set setResults = cache.entrySet(new LikeFilter("getHomeAddress.getCity", "S%"));

    Set setResults = cache.entrySet(createFilter("homeAddress.city like 'S%'"));

    Set setResults = cache.entrySet(new GreaterFilter("getAge", nAge));

    // Initialize nAge and aEnv

    final int nAge = 42;

    Object[] aEnv = new Object[] {new Integer(nAge)};

    ...

    Set setResults = cache.entrySet(createFilter("age > ?1",aEnv));

    Set setResults = cache.entrySet(new AndFilter(new LikeFilter(new KeyExtractor("getLastName"), "S%", (char) 0, false), new EqualsFilter("getHomeAddress.getState", "MA")));

    Set setResults = cache.entrySet(createFilter("lastName like 'S%' and homeAddress.state = 'MA'"));


  6. Replace the calls to the *Filter methods in the aggregate statements with calls to createFilter with the appropriate Coherence Query Language.

    Table 6-3 lists the *Filter instances and their createFilter equivalents.

    Table 6-3 Filter Statements and their Equivalent createFilter Statements in Aggregations

    Replace this *Filter statement... With the equivalent createFilter statement

    System.out.println("count > " + nAge + ": "+ cache.aggregate(new GreaterFilter("getAge", nAge), new Count()));

    System.out.println("count > " + nAge + ": " + cache.aggregate(createFilter("age > ?1", aEnv), new Count()));

    System.out.println("min age: " + cache.aggregate(AlwaysFilter.INSTANCE, new LongMin("getAge")));

    Filter always = createFilter("true");

    System.out.println("min age: " + cache.aggregate(always, new LongMin("getAge")));

    System.out.println("avg age: " + cache.aggregate(AlwaysFilter.INSTANCE, new DoubleAverage("getAge")));

    System.out.println("avg age: " + cache.aggregate(always, new DoubleAverage("getAge")));

    System.out.println("max age: " + cache.aggregate(AlwaysFilter.INSTANCE, new LongMax("getAge")));

    System.out.println("max age: " + cache.aggregate(always, new LongMax("getAge")));


When you are finished with the code replacements, QueryExample.java should look similar to Example 6-1.

Example 6-1 Edited QueryExample File

package com.oracle.handson;
 
import com.tangosol.net.CacheFactory;
import com.tangosol.net.NamedCache;
 
import com.tangosol.util.Filter;
import static com.tangosol.util.QueryHelper.*;
 
import com.tangosol.util.aggregator.Count;
// import com.tangosol.util.extractor.ChainedExtractor;
// import com.tangosol.util.extractor.KeyExtractor;
// import com.tangosol.util.extractor.ReflectionExtractor;
 
// import com.tangosol.util.aggregator.Count;
import com.tangosol.util.aggregator.DoubleAverage;
import com.tangosol.util.aggregator.LongMax;
import com.tangosol.util.aggregator.LongMin;
 
 
// import com.tangosol.util.filter.AlwaysFilter;
// import com.tangosol.util.filter.AndFilter;
// import com.tangosol.util.filter.EqualsFilter;
// import com.tangosol.util.filter.GreaterFilter;
// import com.tangosol.util.filter.LikeFilter;
// import com.tangosol.util.filter.NotEqualsFilter;
 
import java.util.Iterator;
import java.util.Set;
 
 
/**
* QueryExample runs sample queries for contacts.
*
*/
public class QueryExample{
  
    // ----- QueryExample methods ---------------------------------------
 
    public static void main(String[] args) {
      NamedCache cache = CacheFactory.getCache("ContactsCache");
       query(cache);
    }
    /**
    * Perform the example queries
    *
    */
     public static void query(NamedCache cache)
        {
         // Add indexes to make queries more efficient
       // ReflectionExtractor reflectAddrHome =
       //         new ReflectionExtractor("getHomeAddress");
 
        // Add an index for the age
        // cache.addIndex(new ReflectionExtractor("getAge"), true, null);
        cache.addIndex(createExtractor("age"), true, null);
 
        // Add index for state within home address
        // cache.addIndex(new ChainedExtractor(reflectAddrHome,
        //        new ReflectionExtractor("getState")), true, null);
       cache.addIndex(createExtractor("homeAddress.state"), false, null); 
 
        // Add index for state within work address
        // cache.addIndex(new ChainedExtractor(
        //        new ReflectionExtractor("getWorkAddress"),
        //        new ReflectionExtractor("getState")), true, null);
        cache.addIndex(createExtractor("workAddress.state"),false, null); 
 
        // Add index for city within home address
        // cache.addIndex(new ChainedExtractor(reflectAddrHome,
        //        new ReflectionExtractor("getCity")), true, null);
        cache.addIndex(createExtractor("homeAddress.city"), true,  null); 
 
        // Find all contacts who live in Massachusetts
        // Set setResults = cache.entrySet(new EqualsFilter(
        //         "getHomeAddress.getState", "MA"));
           Set setResults = cache.entrySet(createFilter("homeAddress.state = 'MA'")); 
            printResults("MA Residents", setResults); 
 
        // Find all contacts who live in Massachusetts and work elsewhere
        // setResults = cache.entrySet(new AndFilter(
        //        new EqualsFilter("getHomeAddress.getState", "MA"),
        //        new NotEqualsFilter("getWorkAddress.getState", "MA")));
            setResults = cache.entrySet(createFilter("homeAddress.state is 'MA' and workAddress is not 'MA'"));
            printResults("MA Residents, Work Elsewhere", setResults);
 
        // Find all contacts whose city name begins with 'S'
        // setResults = cache.entrySet(new LikeFilter("getHomeAddress.getCity",
        //         "S%"));
           setResults = cache.entrySet(createFilter("homeAddress.city like 'S%'")); 
            printResults("City Begins with S", setResults);
 
        final int nAge = 42;
        Object[] aEnv  =  new Object[] {new Integer(nAge)}; 
        // Find all contacts who are older than nAge
        // setResults = cache.entrySet(new GreaterFilter("getAge", nAge));
           setResults = cache.entrySet(createFilter("age > ?1",aEnv)); 
             printResults("Age > " + nAge, setResults);
 
        // Find all contacts with last name beginning with 'S' that live
        // in Massachusetts. Uses both key and value in the query.
        // setResults = cache.entrySet(new AndFilter(
        //     new LikeFilter(new KeyExtractor("getLastName"), "S%",
        //   (char) 0, false),
        //         new EqualsFilter("getHomeAddress.getState", "MA")));
           setResults = cache.entrySet(createFilter("lastName like 'S%' and homeAddress.state = 'MA'"));
            printResults("Last Name Begins with S and State Is MA", setResults);
        
           // Count contacts who are older than nAge
           // System.out.println("count > " + nAge + ": "+ 
           //  cache.aggregate(new GreaterFilter("getAge", nAge), new Count()));
               System.out.println("count > " + nAge + ": " + cache.aggregate(
                    createFilter("age > ?1", aEnv), new Count()));
              
           // Find minimum age
           // System.out.println("min age: " + cache.aggregate(AlwaysFilter.INSTANCE, new LongMin("getAge")));
             Filter always = createFilter("true");
             System.out.println("min age: " + cache.aggregate(always, new LongMin("getAge")));
              
            // Calculate average age
            // System.out.println("avg age: " + cache.aggregate(AlwaysFilter.INSTANCE, new DoubleAverage("getAge")));
               System.out.println("avg age: " + cache.aggregate(always, new DoubleAverage("getAge")));
              
             // Find maximum age
             // System.out.println("max age: " +
             // cache.aggregate(AlwaysFilter.INSTANCE, new LongMax("getAge")));
               System.out.println("max age: " + cache.aggregate(always, new LongMax("getAge")));

 System.out.println("------QueryLanguageExample completed------");
                    
 
 
        }
 
    /**
    * Print results of the query
    *
    * @param sTitle      the title that describes the results
    * @param setResults  a set of query results
    */
    private static void printResults(String sTitle, Set setResults)
        {
        System.out.println(sTitle);
        for (Iterator iter = setResults.iterator(); iter.hasNext(); )
            {
            System.out.println(iter.next());
            }
        }
    }

6.3 Re-running the Query Example

Follow these steps to re-run the query example.

  1. Stop all running cache servers.

  2. Restart the Contacts cache server with contacts-cache-server.cmd.

  3. Run the DataGenerator, LoaderExample, and QueryExample files.

  4. After printing all of the contact information in the cache, it displays the results of the queries. The results should look similar to the following figures.

Figure 6-1 illustrates the output of the "MA Residents" filter.

Figure 6-1 Output of the "MA Residents" Filter

Output of the "MA Residents" filter.

Figure 6-2 illustrates the output of the "MA Residents, Work Elsewhere" filter.

Figure 6-2 Output of the "MA Residents, Work Elsewhere" Filter

MA Residents, Work Elsewhere Filter Output

Figure 6-3 illustrates the output of the "City Begins with S" filter.

Figure 6-3 Output of the "City Begins with S" Filter

Output of the "City Begins with S" Filter

Figure 6-4 illustrates the output of the "Last Name Begins with S and State is MA" filter (empty set) and the output of the aggregators.

Figure 6-4 Output of the State and Age Aggregators

Output of filter and the aggregators.