0

使用com.couchbase.client, java-client版本2.2.7,我无法让使用参数化 IN 子句的 n1ql 二级索引正常工作。请参阅下面的示例索引、查询和 java 代码

指数

CREATE INDEX `indexName` ON `bucketName`(id,docType) USING GSI ;

询问

public static final String COUNT_STATEMENT = "select count(*) as count " +
            "from bucketName " +
            "where docType = 'docId' " +
            "and id IN $ids " + 
            "and publishTimestamp between $startTime and $endTime";

提交查询的代码

public int getCountForDuration(Long startTime, Long endTime, Collection<String> ids){
    List<String> idList = new ArrayList<>(ids);
    JsonObject placeHolders = JsonObject.create()
                                        .put("ids", JsonArray.from(idList))
                                        .put("startTime", startTime)
                                        .put("endTime", endTime);
    N1qlQuery query = N1qlQuery.parameterized(COUNT_STATEMENT, placeHolders)            
    N1qlQueryResult result = bucket.query(query);
    ...
}

在添加参数化之前,我的查询正确使用了这个二级索引。如果我使用主索引,我的查询也有效。

我的问题是如何创建将由我的查询使用的二级索引。

4

2 回答 2

2

索引中的第一个条目(在您的情况下id)不能丢失。所以有缺失的文档id不会出现在索引中。因此,如果您不使用已受索引条件约束的字段,则必须指定它不丢失以确保可以转到您的二级索引。

例如,您可以只查询以下索引type="entityType"

CREATE INDEX `indexName` ON `bucketName`(type) WHERE `type`="entityType"

于 2016-08-09T08:37:53.760 回答
2

我通过添加一个附加is not missing条款解决了这个问题,出于某种原因,这解决了这个问题。相同的解决方案对我来说有效。这是更新的查询:

public static final String COUNT_STATEMENT = "select count(*) as count " +
        "from bucketName " +
        "where id is not missing " + 
        "and docType = 'docId' " +
        "and id IN $ids " + 
        "and publishTimestamp between $startTime and $endTime";

@Ben Wilde 评论 -

“需要“丢失”的原因是因为不能丢失索引中的第一个条目(在 'this' case id 中)。因此,缺少 id 的文档将不会出现在索引中,因此如果您不使用已经受索引设置的条件约束的字段,那么您必须指定它不会丢失以确保可以转到您的二级索引”

于 2016-08-03T01:07:25.057 回答