在索引字段上使用谓词查询

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 实例和我的配置,然后:

例如:

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 没有。当我稍等一下并重试查询时就可以了。看起来索引是异步更新的,对吗?有没有办法避免它?

运行时有两种选择:

代码:

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 问题,请跟进以进行修复。