4

いくつかのキーでドキュメントを発行するマッパーを使用した単純なビューがあります。

    com.couchbase.lite.View view = database.getView(VIEW_NAME);
    if (view.getMap() == null) {
        Mapper map = new Mapper() {
            @Override
            public void map(Map<String, Object> document, Emitter emitter) {
                if ("user".equals(document.get("type"))) {
                    emitter.emit(document.get("name"), document); 
                }
            }
        };
        view.setMap(map, null);
    }

このビューがあれば、カウチベースのマニュアルで説明されているように、setKeys、startKey、endKey、setDescending、setDescending、setSkip などの特定のパラメーターを使用してクエリを作成できます。

私が書いたら

    Query query = view.createQuery();
    List<Object> keys = new ArrayList<>();
    keys.add("User Name");
    query.setKeys(keys);

そのクエリは、「ユーザー名」キーに一致するすべてのドキュメントを返します。

しかし、特定のキーを持つドキュメントを除外 (省略) するクエリを作成する簡単な方法を見つけることができませんでした (setKeys() 関数の反対のように)。

ToDoLite の例で 1 つのハックが見つかりました 。コードは次のようになります。

public static Query getQuery(Database database, final String ignoreUserId) {
    com.couchbase.lite.View view = database.getView(VIEW_NAME);
    if (view.getMap() == null) {
        Mapper map = new Mapper() {
            @Override
            public void map(Map<String, Object> document, Emitter emitter) {
                if ("user".equals(document.get("type"))) {
                    if (ignoreUserId == null ||
                            (ignoreUserId != null &&
                                    !ignoreUserId.equals(document.get("user_id")))) {
                        emitter.emit(document.get("name"), document);
                    }
                }
            }
        };
        view.setMap(map, null);
    }

    Query query = view.createQuery();
    return query;
}

ビューは、最初の呼び出し時に渡したキーignoreUserIdのみを除外し、次の呼び出しでは他のすべてを無視することに注意してください (ビューは最初の呼び出しで 1 回だけ作成されるため)。

したがって、省略したいキーごとに新しいビューを作成する必要があります。しかし、除外したいキーがたくさんある場合、または頻繁に除外する場合は、非効率的でボイラープレートになります。

より良い解決策やハックを知っていますか?


よろしくお願いします

4

1 に答える 1

4

CouchBase は、ここで発行するタイプのクエリ用に設計されていません。特定のドキュメントを除外するのではなく、特定のドキュメントを特定の範囲 (1 つのドキュメントの範囲まで) で識別するために内部で map/reduce を使用するように設計されています。あなたが求めていることは、CouchBase では効率的ではありません。この種のクエリを効率的に実行することが目標である場合は、間違ったテクノロジを使用しています。

ただし、手を縛られていて CouchBase Lite に縛られている場合は、使用しているクエリの種類の範囲内で作業する必要があります。特定の値を除外することは、他のすべての値を含めることとして言い換えることができます。CouchBase でこれを行いたい場合は、除外したい値を含まないように設計された範囲で範囲クエリを使用します。

ここに簡単な概念的な例があります。ビューに "A"、"B"、"C"、"D"、"F"、および "X" のキーを持つドキュメントがあり、結果がドキュメント "D" を除外するクエリを発行するとします。最初に「A」-「C」の範囲クエリを発行し、次に「E」-「Z」の 2 番目の範囲クエリを発行することで、目的の結果を得ることができます。結合された 2 つの結果は、"D" を除くすべてになります。

もちろん、それらは単純なキーです。キーが複雑になるほど、特定の値を除外する範囲のエンドポイントが複雑になります。除外するキーが多いほど、実行する必要のあるクエリも多くなります (N 個の除外された用語に対して N + 1 個のクエリを実行する必要があります)。ビュー内のすべての値を照会し、それらを自分でコードでフィルター処理することにより、おそらくより効率的なシステムが得られるでしょう。

于 2014-08-03T16:19:13.483 に答える