インデックス

Qdrantの主要な特徴の1つは、ベクトルインデックスと従来のインデックスを効果的に組み合わせた点にあります。これは単にベクトルインデックスを持っているだけでは、フィルタリング条件下で効率的なベクトル検索を可能にするには不十分だからです。要するに、ベクトルインデックスはベクトル検索を加速し、ペイロードインデックスはフィルタリングを加速します。

一つの段落内のインデックスは独立して存在しますが、インデックス自体のパラメータはセット全体に対して構成されます。

すべての段落に自動的にインデックスが付けられるわけではありません。これは最適化設定の要件に依存し、通常は格納されているポイントの数に依存します。

ペイロードインデックス

Qdrantにおけるペイロードインデックスは、従来のドキュメント指向データベースにおけるインデックスと類似しています。このインデックスは特定のフィールドとタイプに対して構築され、対応するフィルタ条件に基づいてポイントを迅速に取得するために使用されます。

また、このインデックスはフィルタ条件の基数を正確に推定するために使用され、これはクエリプランナーが検索戦略を選択するのに役立ちます。

インデックスを作成するには、追加の計算リソースとメモリが必要ですので、慎重にインデクシングするフィールドを選択することが重要です。Qdrantはこの選択を代わりに行うのではなく、ユーザーに委任します。

フィールドをインデックス可能としてマークするには、次の方法を使用できます:

PUT /collections/{collection_name}/index

{
    "field_name": "インデックス化するフィールドの名前",
    "field_schema": "keyword"
}

利用可能なフィールドタイプは以下の通りです:

  • keyword - キーワードペイロード用で、一致するフィルタ条件に影響を与えます。
  • integer - 整数ペイロード用で、一致および範囲フィルタ条件に影響を与えます。
  • float - 浮動小数点数ペイロード用で、範囲フィルタ条件に影響を与えます。
  • bool - ブール値ペイロード用で、一致するフィルタ条件に影響を与えます(バージョン1.4.0以降で利用可能)。
  • geo - 地理的ペイロード用で、地理的境界ボックスおよび地理的半径フィルタ条件に影響を与えます。
  • text - キーワード/文字列ペイロードに適した特別なインデックスタイプで、フルテキスト検索のフィルタ条件に影響を与えます。

ペイロードインデックスは追加のメモリを消費する場合がありますので、フィルタ条件で使用されるフィールドのみをインデックス化することを推奨します。多くのフィールドを基準にフィルタリングする必要がある場合、メモリ制約がすべてのフィールドのインデックス化を許可しない場合は、検索結果を最も限定するフィールドを選択することが賢明です。一般的に、ペイロードの値がユニークであればあるほど、インデックスの使用効果が高くなります。

フルテキストインデックス

バージョン0.10.0以降で利用可能

Qdrantは文字列ペイロードに対するフルテキスト検索をサポートしています。フルテキストインデックスにより、ペイロードフィールドに単語やフレーズが存在するかどうかに基づいてポイントをフィルタすることができます。

フルテキストインデックスを構成するには、トークン化パラメータを指定できるため若干複雑です。トークン化は文字列をトークンに分割し、これらのトークンを逆インデックスにインデックスするプロセスです。

フルテキストインデックスを作成するには、次の方法を使用できます:

PUT /collections/{collection_name}/index

{
    "field_name": "インデックス化するフィールドの名前",
    "field_schema": {
        "type": "text",
        "tokenizer": "word",
        "min_token_len": 2,
        "max_token_len": 20,
        "lowercase": true
    }
}

利用可能なトークン化メソッドは以下の通りです:

  • word - スペース、句読点、および特殊文字に基づいて文字列を分割します。
  • whitespace - スペースに基づいて文字列を分割します。
  • prefix - スペース、句読点、および特殊文字に基づいて文字列を分割し、その後それぞれの単語に対して接頭辞インデックスを作成します。例えば、helloh, he, hel, hell, hello としてインデックス化されます。
  • multilingual - charabiaパッケージに基づく特別なトークン化タイプです。これにより、正しいトークン化と多言語の語形変化が可能となります。デフォルトのビルド構成では、qdrantはバイナリファイルのサイズを増加させるため、すべての言語をサポートしていません。中国語、日本語、韓国語はデフォルトで有効になっていませんが、--features multiling-chinese, multiling-japanese, multiling-koreanフラグを使用してソースコードからqdrantをビルドすることで有効にできます。

フルテキストインデックスを使用したクエリの利用例については、フルテキスト一致の例を参照してください。

ベクトルインデックス

ベクトルインデックスは、特定の数学的モデルを用いて構築されたベクトルに基づくデータ構造です。ベクトルインデックスを使用することで、ターゲットベクトルに類似した複数のベクトルを効率的にクエリすることができます。

現在、QdrantはベクトルインデックスとしてHNSWのみを使用しています。

HNSW(階層的ナビゲーション可能なスモールワールドグラフ)は、グラフベースのインデックスアルゴリズムです。特定の規則に従い、グラフのための多層のナビゲーション構造を構築します。この構造では、上位レイヤーは疎でノード間の距離が大きく、下位レイヤーは密でノード間の距離が小さいです。検索はトップレイヤーから開始し、そのレイヤーでターゲットに最も近いノードを見つけてから次のレイヤーに入り、何度も反復することで迅速にターゲット位置に近づくことができます。

性能向上のため、HNSWはグラフの各レイヤーのノードの最大次数をmに制限します。さらに、インデックス構築中にef_constructを、またはターゲットの検索時にefを使用して検索範囲を指定することができます。

これらのパラメータは設定ファイルで構成可能です:

storage:
  hnsw_index:
    m: 16
    ef_construct: 100
    full_scan_threshold: 10000

コレクション作成プロセス中には、efパラメータを構成することができ、デフォルトではef_constructと等しくなります。

HNSWは複数の理由から選択されました。まず第一に、HNSWはQdrantが検索プロセス中にフィルタを変更することを容易にするという高い互換性を持っています。また、公開されているベンチマークテストによると、最も正確で高速なアルゴリズムの1つです。

v1.1.1から利用可能

HNSWのパラメータはhnsw_configを設定することでコレクションや名前付きベクトルごとに細かく調整することができます。

フィルタブルインデックス

単独のペイロードインデックスや単独のベクトルインデックスだけでは、検索にフィルタを適用することに完全に対処することはできません。

フィルタが弱い場合は、HNSWインデックスを直接使用することができます。フィルタが厳格な場合は、ペイロードインデックスを使用し、完全なリスコアリングを行うことができます。しかし、中間的なケースでは、このアプローチは効果的ではありません。

一方で、あまりにも多くのベクトルに対してフルスキャンを行うことはできません。また、過度に厳格なフィルタを使用すると、HNSWグラフが崩れ始めます。

追加のエッジを含めることで、HNSWインデックスを効率的に使用して近隣のベクトルを検索し、グラフ内での検索中にフィルタを適用することができます。

このアプローチにより、条件のチェックのオーバーヘッドが最小限に抑えられます。つまり、検索に参加するポイントのわずかな部分に対してのみ条件を計算する必要があります。