第 2 章 创建 Ickle 查询
Data Grid 提供了一个 Ickle 查询语言,可让您创建关系和全文本查询。
2.1. Ickle 查询
要使用 API,请调用 cache .query ()
方法并提供查询字符串。
例如:
// Remote Query using protobuf Query<Transaction> q = remoteCache.query("from sample_bank_account.Transaction where amount > 20"); // Embedded Query using Java Objects Query<Transaction> q = cache.query("from org.infinispan.sample.Book where price > 20"); // Execute the query QueryResult<Book> queryResult = q.execute();
查询将始终以单个实体类型为目标,并在单个缓存的内容上评估。不支持对多个缓存运行查询,或创建以多个实体类型(连接)为目标的查询。
执行查询并获取结果非常简单,就像调用 Query
对象的 execute ()
方法一样简单。执行之后,对同一实例调用 execute ()
将重新执行查询。
2.1.1. 分页
您可以使用 Query.maxResults (int maxResults)
限制返回的结果数量。这可与 Query.startOffset (long startOffset)
一起使用,来实现结果集的分页。
// 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)
如果您没有为查询实例明确设置 maxResults
,Data Grid 会将查询返回的结果数量限制为 100
。您可以通过设置 query.default-max-results
缓存属性来更改默认限制。
2.1.2. 命中数
QueryResult
对象包含 .hitCount ()
方法,它返回一个 hit count 值,代表查询的结果总数,而不考虑任何分页参数。
另外,QueryResult
对象包含 .isExact ()
方法返回的布尔值,它指示 hit count 号是否准确还是低绑定。因为性能的原因,点击数仅适用于索引的查询。
2.1.2.1. 达到次数准确性
您可以通过设置 hit-count-accuracy
属性来限制所需的点击数的准确性。处理大型数据集时,精确点击数可能会影响性能。将限制设置为达到达到的准确性,可让您获得更快的查询响应,同时确保提供的点击数对应用程序的需求保持足够准确。
hit-count-accuracy
属性的默认准确性限制为 10000
。这意味着,对于任何查询,Data Grid 提供最多 10,000 的点击数。如果有效点击数大于 10,000,则数据网格返回低限估算。您可以通过设置 query.hit-count-accuracy
缓存属性来更改默认限制。或者,也可以在每个查询实例上设置它。
当实际点击数超过 hit-count-accuracy
设置的限制时,.isExact ()
方法或 hit_count_exact
JSON 字段将为 false
,表示返回的点击数是估算。将此值设置为 Integer。MAX
会为任何查询返回准确的结果,但这可能会严重影响查询性能。
为了获得最佳性能,则属性值比预期的点击数稍高。如果您不要求准确点击数,请将其设为低值。
2.1.3. 迭代
Query
对象具有 .iterator
() 方法,可以完全获得结果。它返回一个在使用后必须关闭的 CloseableIterator
实例。
远程查询的迭代支持当前有限,因为它在迭代前首先获取客户端的所有条目。
2.1.4. 命名查询参数
可以不必为每个执行构建一个新的 Query 对象,而是在查询中包含命名参数,这些参数可以在执行前使用实际值替换。这允许定义一次查询,并可以有效地执行多次。参数只能在操作器的右侧使用,并通过提供由 org.infinispan.query.dsl.Expression.param (String paramName)
方法生成的对象来创建查询时定义。定义参数后,可以通过调用 Query.setParameter (parameterName, value)
或 Query.setParameters (parameterMap)
来设置参数,如以下示例所示。
// 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();
或者,您可以提供一个实际参数值映射以一次性设置多个参数:
一次设置多个命名参数
Map<String, Object> parameterMap = new HashMap<>(); parameterMap.put("authorName", "Doe"); parameterMap.put("publicationYear", 2010); query.setParameters(parameterMap);
在首次使用参数执行查询时,执行查询解析、验证和执行规划工作的主要部分。与使用恒定值而不是查询参数类似的查询相比,后续执行期间不会重复这一工作,从而提高性能。
2.1.5. 查询执行
Query
API 提供了两种方法在缓存中执行 Ickle 查询:
-
query.execute ()
运行 SELECT 语句并返回结果。 -
query.executeStatement ()
运行 DELETE 语句并修改数据。
您应该始终调用 executeStatement ()
来修改数据并调用 execute ()
来获取查询的结果。