在索引字段上使用谓词查询
Query with predicate on indexed field
在我的项目中,我最近遇到了一个与配置了 QueryCache 的地图相关的问题。
我有两个字段的实体:
class AccountingRule {
long key;
String code;
}
它的地图配置包括 QueryCache 配置:
MapConfig mapConfig = new MapConfig("AccountingRule")
.setInMemoryFormat(InMemoryFormat.BINARY)
.setReadBackupData(true)
.setBackupCount(1)
.addQueryCacheConfig(new QueryCacheConfig()
.setName("AccountingRule")
.setPredicateConfig(new PredicateConfig(TruePredicate.INSTANCE))
.setIncludeValue(true)
.setPopulate(true)
.setDelaySeconds(0)
);
主要是 运行 hazelcast 实例和我的配置,然后:
- 向 QueryCache 添加索引
- 将实体放入 IMap
- 通过检查 QueryCache.get 是否返回插入的实体
等到插入传播到 QueryCache
- 使用索引字段上的谓词从 QueryCache 获取相同的实体
例如:
HazelcastInstance hazelcast = createHazelcastInstance();
IMap<Long, AccountingRule> map = hazelcast.getMap("AccountingRule");
QueryCache<Long, AccountingRule> queryCache = map.getQueryCache("AccountingRule");
queryCache.addIndex("code", false);
while (true) {
AccountingRule ar = newAccountingRule();
map.put(ar.getKey(), ar);
// wait for query cache
AccountingRule fromQueryCache = queryCache.get(ar.getKey());
while (fromQueryCache == null) {
log.info("Waiting for query cache");
fromQueryCache = queryCache.get(AccountingRule.class, ar.getKey());
}
log.info("query cache updated");
// get entity from query cache using predicate
Predicate codePredicate = equal("code", ar.getCode());
AccountingRule fromQueryCacheWithPredicate = getOnlyElement(queryCache.values(codePredicate), null);
if (fromQueryCacheWithPredicate == null) {
log.error("AccountingRule with id {} from query cash is null", ar.getKey());
System.exit(1);
}
}
不幸的是它失败了。 QueryCache.get 返回实体但基于索引字段上的谓词查询 returns 没有。当我稍等一下并重试查询时就可以了。看起来索引是异步更新的,对吗?有没有办法避免它?
运行时有两种选择:
- 删除索引 -> 没有索引没问题:)
- 像这样在 QueryCache conf 中声明索引,而不是在 main 中:
代码:
MapConfig mapConfig = new MapConfig("AccountingRule")
.setInMemoryFormat(InMemoryFormat.BINARY)
.setReadBackupData(true)
.setBackupCount(1)
.addQueryCacheConfig(new QueryCacheConfig()
.setName("AccountingRule")
.setPredicateConfig(new PredicateConfig(TruePredicate.INSTANCE))
.setIncludeValue(true)
.setPopulate(true)
.setDelaySeconds(0)
.addIndexConfig(new MapIndexConfig("code", false))
);
问题是为什么当我不在配置中添加索引时它不能正常工作?
这个问题好像有bug。当您执行 QueryCache.addIndex
时,仅当查询缓存中有条目时才会创建索引。此外,根本不会创建源自 Config
(编程式或声明式)的索引,查询缓存中的查询 运行 会进行全面扫描。
我看到您已经针对此问题 (#12358) 创建了一个 Github 问题,请跟进以进行修复。
在我的项目中,我最近遇到了一个与配置了 QueryCache 的地图相关的问题。
我有两个字段的实体:
class AccountingRule {
long key;
String code;
}
它的地图配置包括 QueryCache 配置:
MapConfig mapConfig = new MapConfig("AccountingRule")
.setInMemoryFormat(InMemoryFormat.BINARY)
.setReadBackupData(true)
.setBackupCount(1)
.addQueryCacheConfig(new QueryCacheConfig()
.setName("AccountingRule")
.setPredicateConfig(new PredicateConfig(TruePredicate.INSTANCE))
.setIncludeValue(true)
.setPopulate(true)
.setDelaySeconds(0)
);
主要是 运行 hazelcast 实例和我的配置,然后:
- 向 QueryCache 添加索引
- 将实体放入 IMap
- 通过检查 QueryCache.get 是否返回插入的实体 等到插入传播到 QueryCache
- 使用索引字段上的谓词从 QueryCache 获取相同的实体
例如:
HazelcastInstance hazelcast = createHazelcastInstance();
IMap<Long, AccountingRule> map = hazelcast.getMap("AccountingRule");
QueryCache<Long, AccountingRule> queryCache = map.getQueryCache("AccountingRule");
queryCache.addIndex("code", false);
while (true) {
AccountingRule ar = newAccountingRule();
map.put(ar.getKey(), ar);
// wait for query cache
AccountingRule fromQueryCache = queryCache.get(ar.getKey());
while (fromQueryCache == null) {
log.info("Waiting for query cache");
fromQueryCache = queryCache.get(AccountingRule.class, ar.getKey());
}
log.info("query cache updated");
// get entity from query cache using predicate
Predicate codePredicate = equal("code", ar.getCode());
AccountingRule fromQueryCacheWithPredicate = getOnlyElement(queryCache.values(codePredicate), null);
if (fromQueryCacheWithPredicate == null) {
log.error("AccountingRule with id {} from query cash is null", ar.getKey());
System.exit(1);
}
}
不幸的是它失败了。 QueryCache.get 返回实体但基于索引字段上的谓词查询 returns 没有。当我稍等一下并重试查询时就可以了。看起来索引是异步更新的,对吗?有没有办法避免它?
运行时有两种选择:
- 删除索引 -> 没有索引没问题:)
- 像这样在 QueryCache conf 中声明索引,而不是在 main 中:
代码:
MapConfig mapConfig = new MapConfig("AccountingRule")
.setInMemoryFormat(InMemoryFormat.BINARY)
.setReadBackupData(true)
.setBackupCount(1)
.addQueryCacheConfig(new QueryCacheConfig()
.setName("AccountingRule")
.setPredicateConfig(new PredicateConfig(TruePredicate.INSTANCE))
.setIncludeValue(true)
.setPopulate(true)
.setDelaySeconds(0)
.addIndexConfig(new MapIndexConfig("code", false))
);
问题是为什么当我不在配置中添加索引时它不能正常工作?
这个问题好像有bug。当您执行 QueryCache.addIndex
时,仅当查询缓存中有条目时才会创建索引。此外,根本不会创建源自 Config
(编程式或声明式)的索引,查询缓存中的查询 运行 会进行全面扫描。
我看到您已经针对此问题 (#12358) 创建了一个 Github 问题,请跟进以进行修复。