org.apache.ignite.internal.processors.cache.query

## Interface CacheQuery<T>

All Known Implementing Classes:
  GridCacheQueryAdapter

    public interface CacheQuery<T>

Main API for configuring and executing cache queries.

# SQL Queries

`SQL` query allows to execute distributed cache queries using standard SQL syntax. All values participating in where clauses or joins must be annotated with `QuerySqlField` annotation.

## Field Queries

By default `select` clause is ignored as query result contains full objects. This type of query replaces full objects with individual fields. Note that selected fields must be annotated with `QuerySqlField` annotation.

## Cross-Cache Queries

You are allowed to query data from several caches. Cache that this query was created on is treated as default schema in this case. Other caches can be referenced by their names.

Note that cache name is case sensitive and has to always be specified in double quotes. Here is an example of cross cache query (note that 'replicated' and 'partitioned' are cache names for replicated and partitioned caches accordingly):

     CacheQuery<Map.Entry<Integer, FactPurchase>> storePurchases = cache.queries().createSqlQuery(
         Purchase.class,
         "from \"replicated\".Store, \"partitioned\".Purchase where Store.id=Purchase.storeId and Store.id=?");

## Custom functions in SQL queries.

It is possible to write custom Java methods and call then form SQL queries. These methods must be public static and annotated with `QuerySqlFunction`. Classes containing these methods must be registered in `CacheConfiguration.setSqlFunctionClasses(Class[])`.

# Full Text Queries

Ignite supports full text queries based on Apache Lucene engine. Note that all fields that are expected to show up in text query results must be annotated with `QueryTextField` annotation.

# Scan Queries

Sometimes when it is known in advance that SQL query will cause a full data scan, or whenever data set is relatively small, the full scan query may be used. This query will iterate over all cache entries, skipping over entries that don't pass the optionally provided key-value filter.

## Limitations

Data in Ignite cache is usually distributed across several nodes, so some queries may not work as expected. Keep in mind following limitations (not applied if data is queried from one node only):

- `Group by` and `sort by` statements are applied separately on each node, so result set will likely be incorrectly grouped or sorted after results from multiple remote nodes are grouped together.
- Aggregation functions like `sum`, `max`, `avg`, etc. are also applied on each node. Therefore you will get several results containing aggregated values, one for each node.
- Joins will work correctly only if joined objects are stored in colocated mode or at least one side of the join is stored in `CacheMode.REPLICATED` cache. Refer to `AffinityKey` javadoc for more information about colocation.

# Query usage

As an example, suppose we have data model consisting of `'Employee'` and `'Organization'` classes defined as follows:

     public class Organization {
         // Indexed field.
         @QuerySqlField(index = true)
         private long id;

         // Indexed field.
         @QuerySqlField(index = true)
         private String name;
         ...
     }

     public class Person {
         // Indexed field.
         @QuerySqlField(index = true)
         private long id;

         // Indexed field (Organization ID, used as a foreign key).
         @QuerySqlField(index = true)
         private long orgId;

         // Without SQL field annotation, this field cannot be used in queries.
         private String name;

         // Not indexed field.
         @QuerySqlField
         private double salary;

         // Index for text search.
         @QueryTextField
         private String resume;
         ...
     }

Then you can create and execute queries that check various salary ranges like so:

     Cache<Long, Person> cache = G.grid().cache();
     ...
     // Create query which selects salaries based on range for all employees
     // that work for a certain company.
     CacheQuery<Map.Entry<Long, Person>> qry = cache.queries().createSqlQuery(Person.class,
         "from Person, Organization where Person.orgId = Organization.id " +
             "and Organization.name = ? and Person.salary > ? and Person.salary <= ?");

     // Query all nodes to find all cached Ignite employees
     // with salaries less than 1000.
     qry.execute("Ignition", 0, 1000);

     // Query only remote nodes to find all remotely cached Ignite employees
     // with salaries greater than 1000 and less than 2000.
     qry.projection(grid.remoteProjection()).execute("Ignition", 1000, 2000);

Here is a possible query that will use Lucene text search to scan all resumes to check if employees have `Master` degree:

     CacheQuery<Map.Entry<Long, Person>> mastersQry =
         cache.queries().createFullTextQuery(Person.class, "Master");

     // Query all cache nodes.
     mastersQry.execute();

# Geo-Spatial Indexes and Queries

Ignite also support Geo-Spatial Indexes. Here is an example of geo-spatial index:

     private class MapPoint implements Serializable {
         // Geospatial index.
         @QuerySqlField(index = true)
         private com.vividsolutions.jts.geom.Point location;

         // Not indexed field.
         @QuerySqlField
         private String name;

         public MapPoint(com.vividsolutions.jts.geom.Point location, String name) {
             this.location = location;
             this.name = name;
         }
     }

Example of spatial query on the geo-indexed field from above:

     com.vividsolutions.jts.geom.GeometryFactory factory = new com.vividsolutions.jts.geom.GeometryFactory();

     com.vividsolutions.jts.geom.Polygon square = factory.createPolygon(new Coordinate[] {
         new com.vividsolutions.jts.geom.Coordinate(0, 0),
         new com.vividsolutions.jts.geom.Coordinate(0, 100),
         new com.vividsolutions.jts.geom.Coordinate(100, 100),
         new com.vividsolutions.jts.geom.Coordinate(100, 0),
         new com.vividsolutions.jts.geom.Coordinate(0, 0)
     });

     Map.Entry<String, UserData> records = cache.queries().createSqlQuery(MapPoint.class, "select * from MapPoint where location && ?")
         .queryArguments(square)
         .execute()
         .get();

### Method Summary

Methods
`CacheQuery<T>` `enableDedup(boolean dedup)` Sets whether or not to deduplicate query result set.
`<R> CacheQueryFuture<R>` `execute(IgniteReducer<T,R> rmtReducer, Object... args)` Executes the query the same way as `execute(Object...)` method but reduces result remotely.
`CacheQueryFuture<T>` `execute(Object... args)` Executes the query and returns the query future.
`GridCloseableIterator` `executeScanQuery()`
`CacheQuery<T>` `includeBackups(boolean incBackups)` Sets whether or not to include backup entries into query result.
`CacheQuery<T>` `keepAll(boolean keepAll)` Sets whether or not to keep all query results local.
`QueryMetrics` `metrics()` Gets metrics for this query.
`CacheQuery<T>` `pageSize(int pageSize)` Sets result page size.
`CacheQuery<T>` `projection(ClusterGroup prj)` Sets optional grid projection to execute this query on.
`void` `resetMetrics()` Resets metrics for this query.
`CacheQuery<T>` `timeout(long timeout)` Sets query timeout.

### Method Detail

#### pageSize

    CacheQuery<T> pageSize(int pageSize)

Sets result page size. If not provided, `Query.DFLT_PAGE_SIZE` will be used. Results are returned from queried nodes one page at a tme.

Parameters:
  `pageSize` - Page size.
Returns:
  `this` query instance for chaining.

#### timeout

    CacheQuery<T> timeout(long timeout)

Sets query timeout. `0` means there is no timeout (this is a default value).

Parameters:
  `timeout` - Query timeout.
Returns:
  `this` query instance for chaining.

#### keepAll

    CacheQuery<T> keepAll(boolean keepAll)

Sets whether or not to keep all query results local. If not - only the current page is kept locally. Default value is `true`.

Parameters:
  `keepAll` - Keep results or not.
Returns:
  `this` query instance for chaining.

#### includeBackups

    CacheQuery<T> includeBackups(boolean incBackups)

Sets whether or not to include backup entries into query result. This flag is `false` by default.

Parameters:
  `incBackups` - Query `includeBackups` flag.
Returns:
  `this` query instance for chaining.

#### enableDedup

    CacheQuery<T> enableDedup(boolean dedup)

Sets whether or not to deduplicate query result set. If this flag is `true` then query result will not contain some key more than once even if several nodes returned entries with the same keys. Default value is `false`.

Parameters:
  `dedup` - Query `enableDedup` flag.
Returns:
  `this` query instance for chaining.

#### projection

    CacheQuery<T> projection(ClusterGroup prj)

Sets optional grid projection to execute this query on.

Parameters:
  `prj` - Projection.
Returns:
  `this` query instance for chaining.

#### execute

    CacheQueryFuture<T> execute(@Nullable
                              Object... args)

Executes the query and returns the query future. Caller may decide to iterate over the returned future directly in which case the iterator may block until the next value will become available, or wait for the whole query to finish by calling any of the `'get(..)'` methods on the returned future. If `keepAll(boolean)` flag is set to `false`, then `'get(..)'` methods will only return the last page received, otherwise all pages will be accumulated and returned to user as a collection.

Note that if the passed in grid projection is a local node, then query will be executed locally without distribution to other nodes.

Also note that query state cannot be changed (clause, timeout etc.), except arguments, if this method was called at least once.

Parameters:
  `args` - Optional arguments.
Returns:
  Future for the query result.

#### execute

    <R> CacheQueryFuture<R> execute(IgniteReducer<T,R> rmtReducer,
                                  @Nullable
                                  Object... args)

Executes the query the same way as `execute(Object...)` method but reduces result remotely.

Parameters:
  `rmtReducer` - Remote reducer.
  `args` - Optional arguments.
Returns:
  Future for the query result.

#### metrics

    QueryMetrics metrics()

Gets metrics for this query.

Returns:
  Query metrics.

#### resetMetrics

    void resetMetrics()

Resets metrics for this query.

#### executeScanQuery

    GridCloseableIterator executeScanQuery()
                                           throws IgniteCheckedException

Returns:
  Scan query iterator.
Throws:
  `IgniteCheckedException`

2017 Copyright © Apache Software Foundation

Follow @ApacheIgnite

Ignite Fabric | : ver. 2.1.0
Release Date | : July 20 2017