我正在尝试根据我在CouchDB上创建的Map / Reduce视图从java执行查询。 我的地图功能如下所示:
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);
}
}
}
和Reduce功能:
function (key, values, rereduce) {
return sum(values);
}
从Futon界面执行时,视图似乎正常工作(尽管没有指定键)。 我要做的是计算属于单个组的某些doc类型的数量。我想使用'userID'和组的名称作为键来查询该视图。
我正在使用Ektorp库来管理CouchDB数据,如果我在没有键的情况下执行此查询它会返回标量值,否则它只会输出一个错误,说明对于reduce query 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(List)类型的列表 - 当然使用CouchDbRepositorySupport - 并且不能与reduce类型查询一起使用(据我所知)。
有没有办法使用指定的reduce函数执行查询,使用Ektorp库执行具有2个或更多值的复杂键?任何例子都高度赞赏。
答案 0 :(得分:3)
除了克里斯的回答:
请注意,当您要查询文档 一组密钥,不以查找文档时,会使用ViewQuery.keys()
(s)带有复杂的钥匙。
与Kris的回答一样,以下示例将获得与指定的键(不“键”)匹配的文档
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()
。 (仅对部分密钥查询有用)
答案 1 :(得分:2)
好的,我找到了使用试错法的解决方案:
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中检索标量值。