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

时间:2018-02-15 16:49:38

标签: indexing hazelcast query-cache

在我的项目中,我最近遇到了与配置了QueryCache的Map相关的问题。

我有两个字段的实体:

class AccountingRule {
    long key;
    String code;
}

映射包含QueryCache配置的Map的配置:

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)
    );

在main中,我使用我的配置运行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返回实体,但基于索引字段的谓词的查询不返回任何内容。当我稍等一下并重试查询时,没关系。它看起来像索引是异步更新我是对的吗?有没有选择可以避免它?

工作时有两种选择:

  • 删除索引 - &gt;没有索引没问题:)
  • 在这样的QueryCache中声明索引,而不是在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))
    );

问题是为什么当我在配置中添加索引时它不能正常工作?

1 个答案:

答案 0 :(得分:1)

看起来这个问题存在漏洞。执行QueryCache.addIndex时,只有在查询缓存中有条目时才会创建索引。此外,根本不会创建源自Config(编程或声明)的索引,并且在查询缓存上运行的查询会进行全扫描。

我发现您已经针对此问题创建了一个Github问题(#12358),请按照此说明进行修复。

相关问题