来自 Ektorp 的 CouchDB Map/Reduce 视图查询

Posted

技术标签:

【中文标题】来自 Ektorp 的 CouchDB Map/Reduce 视图查询【英文标题】:CouchDB Map/Reduce view query from Ektorp 【发布时间】:2012-09-13 14:59:12 【问题描述】:

我正在尝试从 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();

上面的例子没有指定'keys'。 我还有其他使用 ComplexKey 的查询,例如:

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

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

是否有任何方法可以使用 Ektorp 库在指定 reduce 函数和具有 2 个或更多值的复杂键的情况下执行查询?任何例子都非常感谢。

【问题讨论】:

【参考方案1】:

好的,我通过反复试验找到了解决方案:

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(...)' 对我不起作用(它需要一个集合作为参数)。 (有关 .key().keys() 之间区别的解释,请参阅 Hendy 的回答)

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

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

【讨论】:

你也可以使用.key(ComplexKey.of(string1, string2, ...))【参考方案2】:

除了克里斯的回答:

请注意,ViewQuery.keys() 用于查询匹配一组键文档用于查找文档) 具有复杂的键。

像 Kris 的回答一样,以下示例将获取与指定 key 匹配的文档(not "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() 来自 guava library。

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

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

【讨论】:

以上是关于来自 Ektorp 的 CouchDB Map/Reduce 视图查询的主要内容,如果未能解决你的问题,请参考以下文章

通过flask/python在html中显示来自couchDB的图像附加

在 CouchDB 上进行预检的 CORS 请求

使用 CouchDB Android 进行用户身份验证

CouchDB:根据时间戳返回最新类型的文档

CouchDB 视图 - 列表功能性能受到影响?

通过更新处理程序向 couchDB 提交表单不起作用