1

我正在尝试从 java 对我在 CouchDB 上创建的 Map/Reduce 视图执行查询。我的地图功能如下所示:

function(doc) {
  if(doc.type == 'SPECIFIC_DOC_TYPE_NAME' && doc.userID){
    for(var g in doc.groupList){
        emit([doc.userID,doc.groupList[g].name],1);
    }
  }
}

和减少功能:

  function (key, values, rereduce) {
        return sum(values); 
}

从 Futon 界面执行时,该视图似乎正在工作(尽管没有指定键)。我要做的是计算属于单个组的某些文档类型的数量。我想使用“userID”和组名作为键来查询该视图。

我正在使用 Ektorp 库来管理 CouchDB 数据,如果我在没有键的情况下执行此查询,它会返回标量值,否则它只会打印一个错误,说明必须指定 reduce 查询 group=true。

我尝试了以下方法:

ViewQuery query = createQuery("some_doc_name");
        List<String> keys = new ArrayList<String>();
        keys.add(grupaName);
        keys.add(uzytkownikID);
        query.group(true);
        query.groupLevel(2);
        query.dbPath(db.path());
        query.designDocId(stdDesignDocumentId);
        query.keys(keys);
        ViewResult r = db.queryView(query);
        return r.getRows().get(0).getValueAsInt();

上面的示例在没有指定“键”的情况下工作。我还有其他使用 ComplexKey 的查询,例如:

ComplexKey key = ComplexKey.of(userID);
return queryView("list_by_userID",key);

但这仅返回 T 类型(列表)的列表 - 当然使用 CouchDbRepositorySupport - 并且不能与减少类型查询一起使用(据我所知)。

有没有什么方法可以使用 Ektorp 库在指定 reduce 函数和具有 2 个或更多值的复杂键的情况下执行查询?任何例子都受到高度赞赏。

4

2 回答 2

3

好的,我找到了使用试错法的解决方案:

public int getNumberOfDocsAssigned(String userID, String groupName) {
        ViewQuery query = createQuery("list_by_userID")
                .group(true)
                .dbPath(db.path())
                .designDocId(stdDesignDocumentId)
                .key(new String[]{userID,groupName});
        ViewResult r = db.queryView(query);
        return r.getRows().get(0).getValueAsInt();
    }

因此,关键是将复杂键不是键)实际上作为包含字符串数组的单个(但复杂)键发送,由于某种原因,方法 '.keys(...)' 对我不起作用(它需要一个 Collection 作为参数). (有关差异的解释.key().keys()请参阅 Hendy 的回答)

此方法计算分配给特定用户(由“userID”指定)和特定组(由“groupName”指定)的所有文档。

希望能帮助任何执行 map/reduce 查询以使用 Ektorp 查询从 CouchDB 检索标量值的人。

于 2012-09-13T19:01:30.903 回答
3

除了克里斯的回答:

请注意,ViewQuery.keys()当您要查询与一组键匹配的文档时使用它,而不是用于查找具有复杂键的文档。

像克里斯的回答一样,以下示例将获得与指定匹配的文档(不是“键”)

viewQuery.key("hello");                             // simple key
viewQuery.key(documentSlug);                        // simple key
viewQuery.key(new String[] { userID, groupName });  // complex key, using array
viewQuery.key(ComplexKey.of(userID, groupName));    // complex key, using ComplexKey

另一方面,以下示例将获取与指定匹配的文档,其中每个键可能是简单键或复杂键:

// simple key: in essence, same as using .key()
viewQuery.keys(ImmutableSet.of("hello"));
viewQuery.keys(ImmutableSet.of(documentSlug1));
// simple keys
viewQuery.keys(ImmutableSet.of("hello", "world"));
viewQuery.keys(ImmutableSet.of(documentSlug1, documentSlug2));
// complex key: in essence, same as using .key()
viewQuery.keys(ImmutableSet.of(
    new String[] { "hello", "world" } ));
viewQuery.keys(ImmutableSet.of(
    new String[] { userID1, groupName1 } ));
// complex keys
viewQuery.keys(ImmutableSet.of(
    new String[] { "hello", "world" },
    new String[] { "Mary", "Jane" } ));
viewQuery.keys(ImmutableSet.of(
    new String[] { userID1, groupName1 },
    new String[] { userID2, groupName2 } ));
// a simple key and a complex key. while technically possible,
// I don't think anybody actually does this
viewQuery.keys(ImmutableSet.of(
    "hello",
    new String[] { "Mary", "Jane" } ));

注意:ImmutableSet.of()来自番石榴库

new Object[] { ... }似乎有相同的行为ComplexKey.of( ... )

此外,还有startKey()endKey()用于使用部分键进行查询。要发送一个空对象{},请使用ComplexKey.emptyObject(). (仅对部分键查询有用)

于 2013-09-28T06:10:09.690 回答