私のアプリケーションでは、ドキュメントの SQL に似たクエリが必要です。全体像は、特定の「タイプ」のcouchdbドキュメントを示すページ分割されたテーブルを含むページがあることです。タイムスタンプ、顧客名、米国の州、さまざまな数値フィールドなど、約 15 の検索可能な列があります。これらの列はすべて注文可能で、ユーザーが各フィールドでフィルター処理できるフィルター フォームもあります。
より具体的な例として、顧客がいくつかのフィルター オプションを設定し、2 ページ目に続いた結果である典型的なクエリを以下に示します。問題を説明するためだけに、pseodo-sql コードで記述されています。
timestamp > last_weeks_monday_epoch AND timestamp < this_weeks_monday_epoch AND marked_as_test = False AND dataspace="production" AND fico > 650
SORT BY timestamp DESC
LIMIT 15
SKIP 15
SQL に似たデータベースを使用している場合、これは些細な問題ですが、couchdb の方がはるかに楽しいです ;) これを解決するために、出力された行の次の構造を持つビューを作成しました。
key: [field, value], id: doc._id, value: null
さて、上記のサンプル クエリを解決するには、一連のクエリを実行する必要があります。
{startkey: ["timestamp", last_weeks_monday_epoch], endkey: ["timestamp", this_weeks_monday_epoch]}
、*_epoch
ここでは整数エポック タイムスタンプ、{key: ["marked_as_test", False]}
、{key: ["dataspace", "production"]}
、{startkey: ["fico", 650], endkey: ["fico", {}]}
上記のクエリの結果が得られたら、一連のドキュメント ID の共通部分を計算し、タイムスタンプ クエリの結果を使用して並べ替えを適用します。最後に、行 15 ~ 30 のドキュメント ID を解決するスライスを適用し、一括取得操作を使用してそれらのコンテンツをダウンロードできます。
言うまでもなく、これは最速の操作ではありません。現在、私が扱っているデータセットは、およそ 10,000 個のドキュメントの大きさです。セットの交点を計算している部分が 4 秒ほどかかることは既に確認できます。明らかに、さらに最適化する必要があります。データセットが 2 倍、3 倍になると、数か月でどれだけ遅くなるかを考えるのが怖いです。
では、私が置かれている状況を説明したので、実際の質問をさせてください。
ツールの柔軟性を失うことなく、目標を達成するためのより良い、より自然な方法はありますか?
私が使用したビュー構造は最適ですか? ある時点で、各フィールドの値を生成する個別の map() 関数を使用することを検討していました。これにより、B ツリーは小さくなりますが、インデックスを生成するためのビュー サーバーの作業が増えます。この方法で利益を得ることができますか?
後で結果のスライスを取得するために、大きなセットの交差を計算する必要があるアルゴリズムの部分が気になります。スケーラブルなアプローチではありません。これのためのより良いアルゴリズムを知っている人はいますか?