To use the API, call the cache .query()
method and provide the query string.
For instance:
// Remote Query using protobuf
Query<Transaction> q = remoteCache.create("from sample_bank_account.Transaction where amount > 20");
// Embedded Query using Java Objects
Query<Transaction> q = cache.create("from org.infinispan.sample.Book where price > 20");
// Execute the query
QueryResult<Book> queryResult = q.execute();
Note
|
A query will always target a single entity type and is evaluated over the contents of a single cache. Running a query over multiple caches or creating queries that target several entity types (joins) is not supported. |
Executing the query and fetching the results is as simple as invoking the execute()
method of the Query
object. Once
executed, calling execute()
on the same instance will re-execute the query.
You can limit the number of returned results by using the Query.maxResults(int maxResults)
. This can be used in
conjunction with Query.startOffset(long startOffset)
to achieve pagination of the result set.
// sorted by year and match all books that have "clustering" in their title
// and return the third page of 10 results
Query<Book> query = cache.query("FROM org.infinispan.sample.Book WHERE title like '%clustering%' ORDER BY year").startOffset(20).maxResults(10)
Note
|
If you don’t explicitly set the |
The QueryResult
object includes the .hitCount()
method, which returns a hit count value that represents the total number of results from a query, regardless of any pagination parameter.
Additionally, QueryResult
object contains a boolean value returned by the .isExact()
method which indicates whether the hit count number is exact or a lower bound.
The hit count is only available for indexed queries for performance reasons.
You can limit the required accuracy of hit counts by setting hit-count-accuracy
attribute.
When dealing with large data sets, precise hit counts can impact performance.
Setting a limit to the hit count accuracy, lets you achieve faster query responses while ensuring that the provided hit counts remain sufficiently accurate for your application’s needs.
The default accuracy of the hit-count-accuracy
attribute is limited to 10000
.
This means that for any query, {brandname} provides exact hit count up to maximum of 10,000.
If the effective hit count is higher than 10,000, {brandname} returns a lower bound estimate of the count.
You can change the default limit by setting the query.hit-count-accuracy
cache property.
Alternatively, it can be set on each query instance.
When the actual hit count exceeds the limit set by the hit-count-accuracy
, the .isExact()
method or the hit_count_exact
JSON field will be false
, indicating that the returned hit count is an estimation.
Setting this value to Integer.MAX
would return accurate results for any query, but this can severely impact query performance.
For optimal performance set the property value slightly above the expected hit count. If you do not require accurate hit counts, set it to a low value.
The Query
object has the .iterator()
method to obtain the results lazily. It returns an instance of CloseableIterator
that must be closed after usage.
Note
|
The iteration support for Remote Queries is currently limited, as it will first fetch all entries to the client before iterating. |
Instead of building a new Query object for every execution it is possible to include named parameters in the query which
can be substituted with actual values before execution. This allows a query to be defined once and be efficiently
executed many times. Parameters can only be used on the right-hand side of an operator and are defined when the query is
created by supplying an object produced by the org.infinispan.query.dsl.Expression.param(String paramName)
method to
the operator instead of the usual constant value. Once the parameters have been defined they can be set by invoking either
Query.setParameter(parameterName, value)
or Query.setParameters(parameterMap)
as shown in the examples below.
// Defining a query to search for various authors and publication years
Query<Book> query = cache.query("SELECT title FROM org.infinispan.sample.Book WHERE author = :authorName AND publicationYear = :publicationYear").build();
// Set actual parameter values
query.setParameter("authorName", "Doe");
query.setParameter("publicationYear", 2010);
// Execute the query
List<Book> found = query.execute().list();
Alternatively, you can supply a map of actual parameter values to set multiple parameters at once:
Map<String, Object> parameterMap = new HashMap<>();
parameterMap.put("authorName", "Doe");
parameterMap.put("publicationYear", 2010);
query.setParameters(parameterMap);
Note
|
A significant portion of the query parsing, validation and execution planning effort is performed during the first execution of a query with parameters. This effort is not repeated during subsequent executions leading to better performance compared to a similar query using constant values instead of query parameters. |
The Query
API provides two methods for executing Ickle queries on a cache:
-
Query.execute()
runs a SELECT statement and returns a result. -
Query.executeStatement()
runs a DELETE statement and modifies data.
Note
|
You should always invoke |