複数のタグ検索を CouchDB に実装する方法はありますか? それぞれに複数のタグが付いたドキュメント (投稿) があります。任意のタグ セットでタグ付けされた投稿を見つける必要があります。どうすればいいのですか?もちろん、ビューを複数回呼び出してタグのドキュメントを取得し、それをアプリで整理することもできますが、CouchDB ビューランドで同じことを実現する方法があるかどうかを知りたかったのです。
6 に答える
再帰関数を使用してビューを作成することで、この問題を解決しました。ここで要点https://gist.github.com/820412
最近のバージョンの CouchDBkeys
では、マルチキー ルックアップを可能にする という JSON ドキュメントを使用してビューに POST できます。構造は次のようになります。
{"keys": ["first_tag", "second_tag", "third_tag"]}
これは、それぞれのキーのタグを発行しているビューに POST できます。
このオプションとその他のクエリ オプションについては、こちらに記載されています。
以下は、少し複雑ですが堅実なアルゴリズムを提供するはずだと思います-つまり、非常に多くのドキュメントがある場合でも、最初の結果をすばやく見つけます。おそらく実際にはうまく機能しません:(
単一のタグごとにドキュメントにインデックスを付け、ドキュメント ID を指定します。
[<何らかのタグ>, <ドキュメント ID>]
例: ドキュメント ドキュメント
- タグ付きのdocid1 [青、緑、赤]
- タグ付きのdocid2 [青、黄]
あなたが得る
['青'、'docid1'] ['青'、'docid2'] ['緑'、'docid1'] [「赤」、「docid1」] ['黄'、'docid2']
検索したいタグごとに、[tag, ...] から始まる並列検索を開きます。
タグごとに、現在の検索位置を維持します。すべての検索でドキュメント ID が一致する場合、一致が見つかりました。一致しない場合は、範囲検索を使用して、少なくとも最大のドキュメント ID にスキップしてみてください。繰り返す。
【基本的には合体です。】
スキップは理論的には高速です。これらのドキュメントを見つけるためのインデックスがあります。実際には、サーバーへのすべてのラウンドトリップが原因で、おそらく低速です。そのアルゴリズムをサーバー上で実行される関数にオフロードできるとよいでしょう。それは可能ですか?
1 つの方法は、上記の Ryan Duffield による説明です。一部のクエリは解決しますが、しばらくすると管理できなくなります。もう 1 つの方法は、現在 CouchDB でサポートされていない全文検索を使用することですが、Lucene を使用する外部プラグインがあります。詳細はこちらhttp://wiki.apache.org/couchdb/Full_text_search。
だから、私が理解している限り、答えはNOです。CouchDB は、複数のタグが存在するドキュメントに対してクエリを実行できません (lucene または mysql を使用した回避策はカウントされません。これにより、CouchDB の一部の機能が失われました)。悲しいニュース :(。
(複数のタグが存在する - A または B ではなく、A と B の両方がある)
アップデート! 可能ですが、タグは 2 ~ 3 個に制限されています。
http://wiki.apache.org/couchdb/EntityRelationship
複数のキーによるクエリ
一部のアプリケーションでは、複数のキーを持つエンティティの交差を表示する必要があります。上記の例では、これは「友人」グループと「同僚」グループの両方に属する連絡先のクエリになります。この状況を処理する最も簡単な方法は、キーの 1 つを照会してから、クライアント側の残りのキーでフィルター処理することです。キーの頻度が大きく異なる場合は、最初の呼び出しを行って頻度が最も低いキーを特定し、それを使用してデータベースから最初のドキュメント リストを取得することも有効です。
これが適切でない場合は、キーの組み合わせにインデックスを付けることができますが、特定のドキュメントのインデックスの増加は、そのキーの数に比例します。それでも、小さいキーセットの場合、これはオプションです。キーを注文することができ、より大きなキーのプレフィックスであるキーを省略できるからです。たとえば、キー セット [1 2 3] の場合、可能なキーの組み合わせは [1] [2] [3] [1 2] [1 3] [2 3] [1 2 3] です。キー [3] [1 3] [2 3] [1 2 3] (たとえば、キー [1 2] に一致するドキュメントは startkey=[1,2,null] および endkey のクエリで取得できるため) =[1,2,{}] インデックス エントリの数は 2^(n-1) キーの数になります。
最後のオプションは、couchdb-lucene などの別のインデックスを使用して、そのようなクエリを支援することです。
実際、タグ付けは非常にリレーショナルな問題のようで、CouchDB の設計ではうまく機能しません。そこで、mysql にタグ用の小さなデータベースを 1 つ用意し、実際のドキュメントを CouchDB に保存することにしました。これにより、両方の長所を活かすことができます。この手法には同期に関連する問題がありますが、タグでの検索は sql での効率的な操作であり、コンテンツはレプリケーションやシャーディングについて心配するほど多くはありません。ご回答ありがとうございます。