1

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

リデュース機能:

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

ビューは、Futon インターフェイスから実行されたときに機能しているようです (ただし、キーは指定されていません)。私がやろうとしているのは、単一のグループに属するドキュメント タイプの数を数えることです。「userID」とグループの名前をキーとして使用して、そのビューを照会したいと思います。

CouchDB データを管理するために Ektorp ライブラリを使用しています。キーなしでこのクエリを実行すると、スカラー値が返されます。それ以外の場合は、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 (List) のリストのみを返します - もちろん CouchDbRepositorySupport を使用します - そして、reduce タイプのクエリでは使用できません (私が知っていることから)。

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(...)'が機能しませんでした(引数としてコレクションを取ります)。(との違いの説明については、ヘンディの答え.key()を参照してください).keys()

このメソッドは、特定のユーザー('userID'で指定)および特定のグループ('groupName'で指定)に割り当てられたすべてのドキュメントをカウントします。

Ektorpクエリを使用してCouchDBからスカラー値を取得するためのmap/reduceクエリを実行する人に役立つことを願っています。

于 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 に答える