I'm trying to execute a query from java against a Map/Reduce view I have created on the CouchDB. My map function looks like the following:
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);
}
}
}
and Reduce function:
function (key, values, rereduce) {
return sum(values);
}
The view seems to be working when executed from the Futon interface (without keys specified though). What I'm trying to do is to count number of some doc types belonging to a single group. I want to query that view using 'userID' and name of the group as a keys.
I'm using Ektorp library for managing CouchDB data, if I execute this query without keys it returns the scalar value, otherwise it just prints an error saying that for reduce query group=true must be specified.
I have tried the following:
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();
above example works without 'keys' specified. I have other queries working with ComplexKey like eg:
ComplexKey key = ComplexKey.of(userID);
return queryView("list_by_userID",key);
but this returns only a list of type T (List) - using CouchDbRepositorySupport of course - and cannot be used with reduce type queries (from what I know).
Is there any way to execute the query with reduce function specified and a complex key with 2 or more values using Ektorp library? Any examples highly appreciated.
Addition to Kris's answer:
Note that
ViewQuery.keys()
is used when you want to query for documents matching a set of keys, not for finding document(s) with a complex key.Like Kris's answer, the following samples will get document(s) matching the specified key (not "keys")
The following samples, on the other hand, will get document(s) matching the specified keys, where each key may be either a simple key or a complex key:
Note:
ImmutableSet.of()
is from guava library.new Object[] { ... }
seems to have same behavior asComplexKey.of( ... )
Also, there are
startKey()
andendKey()
for querying using partial key. To send an empty object{}
, useComplexKey.emptyObject()
. (only useful for partial key querying)Ok, I've found the solution using trial and error approach:
So, the point is to send the complex key (not keys) actually as a single (but complex) key containing the String array,
for some reason method '.keys(...)' didn't work for me (it takes a Collection as an argument). (for explanation on difference between.key()
and.keys()
see Hendy's answer)This method counts all documents assigned to the specific user (specified by 'userID') and specific group (specified by 'groupName').
Hope that helps anybody executing map/reduce queries for retrieving scalar values from CouchDB using Ektorp query.