2012-09-13 44 views
1

我想從java執行查詢對我在CouchDB上創建的地圖/減少視圖。 我的地圖功能如下所示:CouchDB地圖/減少從Ektorp查看查詢

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); 
} 

的觀點似乎從被褥界面執行時是工作(雖然沒有指定的鍵)。 我想要做的是統計屬於一個組的一些文檔類型的數量。我想用'userID'和組名作爲鍵來查詢該視圖。

我正在使用Ektorp庫來管理CouchDB數據,如果我在沒有鍵的情況下執行此查詢,它將返回標量值,否則它只會打印一條錯誤消息,指出對於reduce查詢組= 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 - 並不能與用於降低類型的查詢(據我所知) 。

有沒有什麼辦法可以用指定的reduce函數執行查詢,並且有一個使用Ektorp庫的具有2個或更多值的複雜關鍵字?任何例子都非常感謝。

回答

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(...)'不適用於我(它需要一個集合作爲參數)。 (有關差異的解釋.key().keys()之間看到亨迪的答案)

這種方法計算分配給特定用戶(通過「用戶ID」指定)和特定組(由「組名」指定)的所有文件。

希望能夠幫助任何人執行map/reduce查詢以使用Ektorp查詢從CouchDB中檢索標量值。

3

加成克里斯的回答是:

注意ViewQuery.keys()是當你想查詢文件匹配一組鍵的,與複雜的關鍵發現文件(S)不使用。

像克里斯的回答,下面的示例將獲得文件(S)匹配指定「鑰匙」)

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()。 (僅用於部分密鑰查詢)