次の方法で共有


Azure DocumentDB の統合ベクター ストア

Azure DocumentDB の統合ベクター データベースを使用して、AI ベースのアプリケーションを Azure DocumentDB に格納されているデータとシームレスに接続します。 この統合には、Azure OpenAI 埋め込みを使って構築したアプリを含めることができます。 ネイティブに統合されたベクター データベースを使用すると、Azure DocumentDB に直接格納されている高次元ベクター データと、ベクター データの作成元のデータを効率的に格納、インデックス付け、クエリできます。 これにより、データを代替ベクター ストアに転送する必要がなくなり、追加コストが発生します。

ベクター ストアとは

ベクター ストアまたはベクター データベースは、ベクター埋め込みを格納および管理するために設計されたデータベースです。これは、高次元空間でのデータの数学的表現です。 この空間では、各ディメンションがデータの特徴に対応しており、高度なデータを表現するために数万ディメンションが使われる場合があります。 この空間内のベクトルの位置は、その特性を表します。 単語、フレーズ、ドキュメント全体、画像、オーディオ、その他の種類のデータはすべてベクトル化できます。

ベクター ストアのしくみ

ベクター ストアでは、ベクトル検索アルゴリズムを使用して、埋め込みのインデックス作成やクエリを実行します。 よく知られているベクター検索アルゴリズムには、階層ナビゲーション可能 Small World (HNSW)、反転ファイル (IVF)、DiskANN などがあります。 ベクトル検索は、プロパティ フィールドの完全一致ではなく、データ特性に基づいて類似項目を検索するのに便利な方法です。 この手法は、類似したテキストの検索、関連する画像の検索、おすすめ候補の作成、異常の検出などのアプリケーションで役立ちます。 これは、埋め込み API を使用して機械学習モデルを使用して作成したデータの ベクター埋め込 み (数値のリスト) のクエリを実行するために使用されます。 埋め込み API の例としては、Azure OpenAI 埋め込み または Azure 上の Hugging Face があります。 ベクトル検索は、データ ベクトルとクエリ ベクトル間の距離を測定します。 クエリ ベクトルに最も近いデータ ベクトルは、意味的に最も似ていると判明したものです。

Azure DocumentDB の統合ベクター データベースでは、元のデータと共に埋め込みの格納、インデックス作成、クエリを実行できます。 この方法により、データを別の純粋なベクトル データベースに複製する余分なコストがかかりません。 さらに、このアーキテクチャはベクター埋め込みと元のデータを一緒に保持します。これにより、マルチモーダル データ操作がより容易になり、データの一貫性、スケール、パフォーマンスが向上します。

ベクトル データベースのユース ケース

ベクター データベースは、AI とデータ分析の多くの領域で使用されます。 自然言語の理解、画像やビデオの認識、レコメンデーション システムの構築、検索機能の活用などのタスクに役立ちます。 これらは、分析 AI と生成 AI アプリケーションの両方で見つけることができます。

たとえば、ベクトル データベースを使用して次のことを行うことができます。

  • コンテンツ、テーマ、センチメント、スタイルに基づいて類似の画像、ドキュメント、楽曲を特定します。
  • 特徴、機能、ユーザー グループに基づいて類似製品を特定します。
  • 個人の好みに基づいてコンテンツ、製品、またはサービスを推奨します。
  • ユーザー グループの類似点に基づいて、コンテンツ、製品、またはサービスを推奨します。
  • 大規模な選択肢のプールから最も適した潜在的なオプションを特定し、複雑な要件を満たします。
  • 一般的なパターンや通常のパターンとは異なるデータの異常や不正なアクティビティを特定します。
  • AI エージェントの永続メモリを実装します。
  • 取得拡張生成 (RAG) を有効にします。

統合ベクター データベースと純粋ベクター データベース

ベクター データベースの実装には、純粋ベクター データベースと、NoSQL またはリレーショナル データベース内の統合ベクター データベースの 2 つの一般的な種類が存在します。

純粋なベクター データベースは、少量のメタデータと共にベクター埋め込みを効率的に格納および管理します。 埋め込みの派生元のデータ ソースとは別です。

パフォーマンスの高い NoSQL またはリレーショナル データベースに統合されるベクター データベースには、追加の機能が用意されています。 NoSQL またはリレーショナル データベースの統合ベクター データベース は、対応する元のデータと共に埋め込み、インデックス作成、クエリを格納できます。 この方法により、データを別の純粋なベクトル データベースに複製する余分なコストがかかりません。 さらに、ベクター埋め込みと元のデータを一緒に保持すると、マルチモーダル データ操作が容易になり、データの一貫性、スケール、パフォーマンスが向上します。

オープン ソース ベクトル データベース

開発者がベクトル データベースを選択する場合、オープンソースのオプションには多くの利点があります。 オープン ソース とは、ソフトウェアのソース コードを自由に使用できるようにすることを意味し、ユーザーは特定のニーズに応じてデータベースをカスタマイズできます。 この柔軟性は、金融サービス業界の企業など、データに固有の規制要件の対象となる組織にとって有益です。

オープンソース ベクトル データベースのもう 1 つの利点は、コミュニティによる強力なサポートです。 アクティブなユーザー コミュニティは、しばしばこれらのデータベースの開発に寄与し、サポートを提供し、ベスト プラクティスを共有し、イノベーションを促進します。

オープンソース ベクター データベースは "無料" であるため、一部の個人が選択します。つまり、ソフトウェアを取得または使用するコストはかからなくなります。 別の方法として、マネージド ベクトル データベース サービスで提供される無料レベルを使用することもできます。 これらのマネージド サービスは、一定の利用限度額まで無料でアクセスできるだけでなく、メンテナンス、更新、スケーラビリティに対応することで、運用の負担が軽減されます。 そのため、マネージド ベクター データベース サービスの Free レベルを使用することで、管理オーバーヘッドを削減しながらコスト削減を実現できます。 このアプローチを使用すると、データベース管理ではなく、コア アクティビティに集中できます。

最適なオープンソース ベクター データベースを選択する

最適なオープンソース ベクトル データベースを選択するには、いくつかの要素を考慮する必要があります。 データベースが特定のワークロード要件を処理できるかどうかに影響するため、データベースのパフォーマンスとスケーラビリティは非常に重要です。 効率的なインデックス作成とクエリ機能を使用するデータベースでは、通常、最適なパフォーマンスが提供されます。 もう 1 つの要因は、データベースに関するコミュニティのサポートと利用可能なドキュメントです。 堅牢なコミュニティと十分なドキュメントにより、価値のあるサポートが提供されます。 たとえば、 DocumentDB は一般的なオープンソース ベクター データベースです。

最も一般的なオプションは、最適なオプションではない可能性があります。 そのため、機能、サポートされているデータ型、使用する既存のツールやフレームワークとの互換性に基づいて、さまざまなオプションを比較する必要があります。 また、オープンソース ベクター データベースの課題にも留意する必要があります。

オープンソース ベクトル データベースの課題

前述のベクター データベースを含む、ほとんどのオープンソース ベクター データベースは純粋ベクター データベースです。 言い換えると、ベクター埋め込みのみを格納および管理し、少量のメタデータと共に設計されています。 元のデータとは別に機能するため、異なるサービス間でデータを移動する必要があります。 この複雑さにより、コストが増え、複雑になり、運用システムの速度が低下する可能性があります。

また、オープンソース データベースに典型的な課題もあります。

  • セットアップ: データベースをインストール、構成、操作するには、特に複雑なデプロイに関する詳細な知識が必要です。 運用をスケールアップしながらリソースと構成を最適化するには、綿密な監視と調整が必要です。
  • メンテナンス: 独自の更新プログラム、パッチ、およびメンテナンスを管理する必要があります。 機械学習の専門知識だけでは不十分です。また、データベース管理に関する豊富な経験が必要です。
  • サポート: 公式サポートはマネージド サービスに比べると限定的で、コミュニティの支援に依存することが多くなります。

そのため、オープンソース ベクトル データベースは、最初は無料ですが、スケールアップする場合は大きなコストがかかります。 事業の展開にはより多くのハードウェア、熟練した IT スタッフ、高度なインフラストラクチャの管理が必要になり、ハードウェア、人件費、運用コストの増加につながります。 オープンソース ベクトル データベースのスケーリングは、ライセンス料がないにもかかわらず、財政的に厳しい場合があります。

オープンソース ベクトル データベースの課題に対処する

パフォーマンスの高い NoSQL またはリレーショナル データベースに統合されたフル マネージド ベクター データベースでは、オープンソース ベクター データベースの追加コストと複雑さが回避されます。 このようなデータベースでは、対応する元のデータと共に、埋め込みを保存し、インデックスを付け、クエリを実行します。 この方法により、データを別の純粋なベクトル データベースに複製する余分なコストがかかりません。 さらに、ベクター埋め込みと元のデータを一緒に保持すると、マルチモーダル データ操作が容易になり、データの一貫性、スケール、パフォーマンスが向上します。 それと同時に、フル マネージド サービスは、開発者がオープンソース ベクトル データベースの設定、メンテナンス、コミュニティの支援に依存する負担を回避するのに役立ちます。 さらに、一部のマネージド ベクター データベース サービスでは、有効期間無料レベルが提供されます。

たとえば、Azure DocumentDB の統合ベクター データベースがあります。 このセットアップにより、開発者はオープンソース ベクター データベースと同様にコストを節約できます。 ただし、オープン ソースオプションとは異なり、サービス プロバイダーはメンテナンス、更新、スケーリングを自動的に処理します。 アップグレードは迅速かつ簡単に行えますが、運用をスケールアップするときに、総保有コスト (TCO) を低く抑えます。 また、このサービスを使用して、既に運用環境にある MongoDB アプリケーションを簡単にスケーリングすることもできます。

Azure DocumentDB には堅牢なベクター検索機能が用意されており、複雑なデータセット間で高速の類似性検索を実行できます。 Azure DocumentDB でベクター検索を実行するには、まずベクター インデックスを作成する必要があります。 Azure DocumentDB には複数のオプションが用意されていますが、データセットのサイズに基づいて作業を開始するのに役立つ一般的なガイドラインを次に示します。

IVF HNSW DiskANN (推奨)
説明 IVFFlat インデックスは、ベクトルをリストに分割し、クエリ ベクターに最も近いサブセットを検索します。 HNSW インデックスは多層グラフを作成します。 DiskANN は、任意の規模での効率的なベクター検索用に設計された、ほぼ近い近隣検索アルゴリズムです。
主なトレードオフ 長所: ビルド時間が短縮され、メモリ使用量が少なくなります。
短所: クエリのパフォーマンスが低下します (速度と再現率のトレードオフの点で)。
長所: 空のテーブル上では、(速度と再現率のトレードオフの面でより優れた)クエリ性能を実現できます。
短所: ビルド時間が遅くなり、メモリ使用量が多くなります。
長所: あらゆる規模、高いリコール、高スループット、低待機時間で効率的です。
ベクター数 10,000 以下 最大 50,000 最大 500,000 以上
推奨されるクラスター層 M10 または M20 M30 以上 M30 以上

DiskANN インデックスは、M30 以降のレベルで使用できます。 DiskANN インデックスを作成するには、このテンプレートに従って "kind" パラメーター "vector-diskann" 設定します。

{ 
    "createIndexes": "<collection_name>",
    "indexes": [
        {
            "name": "<index_name>",
            "key": {
                "<path_to_property>": "cosmosSearch"
            },
            "cosmosSearchOptions": { 
                "kind": "vector-diskann", 
                "dimensions": <integer_value>,
                "similarity": <string_value>,
                "maxDegree" : <integer_value>, 
                "lBuild" : <integer_value>, 
            } 
        } 
    ] 
}
フィールド タイプ Description
index_name 文字列 インデックスの一意の名前。
path_to_property 文字列 ベクトルを含むプロパティへのパス。 このパスには、最上位のプロパティまたはそのプロパティへのドット表記パスを指定できます。 ベクトルは、インデックスを作成し、ベクトル検索結果で使用するために number[] である必要があります。 double[]など、別の型を使用するベクターを使用すると、ドキュメントのインデックスが作成されなくなります。 インデックスのないドキュメントは、ベクター検索の結果では返されません。
kind 文字列 作成するベクター インデックスの種類。 オプションは vector-ivfvector-hnswvector-diskann です。
dimensions 整数 ベクトルの類似性の次元の数。 DiskANN は最大 16,000 ディメンション ( 製品量子化あり) をサポートし、今後のサポートは 40,000 以上を予定しています。
similarity 文字列 インデックスで使用する類似性メトリック。 可能なオプションは COS (コサイン距離)、L2 (ユークリッド距離)、IP (内積)です。
maxDegree 整数 グラフ内のノードあたりのエッジの最大数。 このパラメーターの範囲は 20 から 2048 です (既定値は 32)。 maxDegree が高いほど、高次元や高精度の要件を持つデータセットに適しています。
lBuild 整数 DiskANN インデックスの構築中に評価される候補ネイバーの数を設定します。 このパラメーターは範囲が 10 から 500 (既定値は 50) であり、精度と計算オーバーヘッドのバランスを取ります。値が大きいほど、インデックスの品質と精度が向上しますが、ビルド時間が長くなります

DiskANN を使用してベクトル検索を実行する

ベクトル検索を実行するには、$search 集計パイプライン ステージを使用し、cosmosSearch 演算子を使用してクエリを実行します。 DiskANN を使用すると、地理空間やテキストベースのフィルターなどの オプション のフィルター処理を使用して、大規模なデータセット全体で高パフォーマンスの検索を行えます。

{
  "$search": {
    "cosmosSearch": {
      "path": "<path_to_property>",
      "query": "<query_vector>",  
      "k": <num_results_to_return>,  
      "filter": {"$and": [
        { "<attribute_1>": { "$eq": <value> } },
        {"<location_attribute>": {"$geoWithin": {"$centerSphere":[[<longitude_integer_value>, <latitude_integer_value>], <radius>]}}}
      ]}
    }
  }
},
フィールド タイプ Description
lSearch 整数 検索対象の動的候補リストのサイズを指定します。 既定値は 40 で、構成可能な範囲は 10 から 1000 です。 値を大きくすると、再現率は向上しますが、検索速度が低下する可能性があります。
k 整数 返される検索結果の数を定義します。 k 値は lSearch 以下である必要があります。

フィルター処理での DiskANN インデックスの使用例

データベースにベクトルを追加する

地理空間フィルターでベクトル検索を使用するには、ベクトル埋め込みと位置座標の両方を含むドキュメントを追加します。 独自のモデル、Azure OpenAI 埋め込み、または Azure 上の Hugging Face などの API を使用して、め込みを作成できます。

from pymongo import MongoClient

client = MongoClient("<your_connection_string>")
db = client["test"]
collection = db["testCollection"]

documents = [
    {"name": "Eugenia Lopez", "bio": "CEO of AdventureWorks", "is_open": 1, "location": [-118.9865, 34.0145], "contentVector": [0.52, 0.20, 0.23]},
    {"name": "Cameron Baker", "bio": "CFO of AdventureWorks", "is_open": 1, "location": [-0.1278, 51.5074], "contentVector": [0.55, 0.89, 0.44]},
    {"name": "Jessie Irwin", "bio": "Director of Our Planet initiative", "is_open": 0, "location": [-118.9865, 33.9855], "contentVector": [0.13, 0.92, 0.85]},
    {"name": "Rory Nguyen", "bio": "President of Our Planet initiative", "is_open": 1, "location": [-119.0000, 33.9855], "contentVector": [0.91, 0.76, 0.83]}
]

collection.insert_many(documents)

DiskANN ベクトル インデックスを作成する

次の例では、フィルター処理機能を使用して DiskANN ベクトル インデックスを設定する方法を示します。 この例には、類似性検索用のベクター インデックスの作成、ベクタープロパティと地理空間プロパティを持つドキュメントの追加、より多くのフィルター処理のためのフィールドのインデックス作成が含まれます。

db.command({
    "createIndexes": "testCollection",
    "indexes": [
        {
            "name": "DiskANNVectorIndex",
            "key": {
                "contentVector": "cosmosSearch"
            },
            "cosmosSearchOptions": {
                "kind": "vector-diskann",
                "dimensions": 3,
                "similarity": "COS",
                "maxDegree": 32,
                "lBuild": 64
            }
        },
        { 
            "name": "is_open",
            "key": { 
                "is_open": 1 
            }      
        },
        {
            "name": "locationIndex",
            "key": {
                "location": 1
            }
        }
    ]
})

このコマンドは、contentVectorexampleCollection フィールドに DiskANN ベクトル インデックスを作成して、類似性検索を有効にします。 また、次のものも追加されます。

  • is_open フィールドのインデックス。ビジネスが開いているかどうかに基づいて結果をフィルター処理できます。
  • 地理的な距離でフィルター処理するための location フィールドの地理空間インデックス。

特定の地理的半径内で類似したベクトルを持つドキュメントを見つけるには、類似性検索に queryVector を指定し、地理空間フィルターを含めます。

query_vector = [0.52, 0.28, 0.12]
pipeline = [
    {
        "$search": {
            "cosmosSearch": {
                "path": "contentVector",
                "vector": query_vector,
                "k": 5,
                "filter": {
                    "$and": [
                        {"is_open": {"$eq": 1}},
                        {"location": {"$geoWithin": {"$centerSphere": [[-119.7192861804, 34.4102485028], 100 / 3963.2]}}}
                    ]
                }
            }
        }
    }
]

results = list(collection.aggregate(pipeline))
for result in results:
    print(result)

この例では、ベクトル類似性検索は、指定された k 類似性メトリックに基づいて上位 COS 件の最も近いベクトルを返します。一方、結果をフィルター処理して、半径 100 マイル以内のオープンしている企業のみを含めます。

[
  {
    similarityScore: 0.9745354109084544,
    document: {
      _id: ObjectId("645acb54413be5502badff94"),
      name: 'Eugenia Lopez',
      bio: 'CEO of AdventureWorks',
      is_open: 1,
      location: [-118.9865, 34.0145],
      contentVector: [0.52, 0.20, 0.23]
    }
  },
  {
    similarityScore: 0.9006955671333992,
    document: {
      _id: ObjectId("645acb54413be5502badff97"),
      name: 'Rory Nguyen',
      bio: 'President of Our Planet initiative',
      is_open: 1,
      location: [-119.7302, 34.4005],
      contentVector: [0.91, 0.76, 0.83]
    }
  }
]

この結果は、半径 100 マイルとオープンしている企業に制限された、queryVector に似た上位のドキュメントを示します。 各結果には類似性スコアとメタデータが含まれており、Azure DocumentDB の DiskANN がエンリッチされた場所に依存する検索エクスペリエンスに対して結合されたベクタークエリと地理空間クエリをどのようにサポートしているかを示します。

ベクター インデックス定義を取得する

コレクションからベクトル インデックス定義を取得するには、listIndexes コマンドを使います。

db.exampleCollection.getIndexes();

この例では、インデックスの作成に使われたすべての vectorIndex パラメーターと共に cosmosSearch が返されます。

[
  { v: 2, key: { _id: 1 }, name: '_id_', ns: 'test.exampleCollection' },
  {
    v: 2,
    key: { vectorContent: 'cosmosSearch' },
    name: 'vectorSearchIndex',
    cosmosSearch: {
      kind: <index_type>, // options are `vector-ivf`, `vector-hnsw`, and `vector-diskann`
      numLists: 3,
      similarity: 'COS',
      dimensions: 3
    },
    ns: 'test.exampleCollection'
  }
]

$lt$lte$eq$neq$gte$gt$in$nin$regex など、サポートされているクエリ フィルターを使用して、ベクトル検索を実行できるようになりました。

事前フィルター処理を使用するには、まず、ベクター インデックスに加えて、フィルター処理するプロパティに標準インデックスを定義する必要があります。 フィルター インデックスを作成する例を次に示します。

db.runCommand({
  "createIndexes": "<collection_name>",
  "indexes": [ {
    "key": {
      "<property_to_filter>": 1
    },
    "name": "<name_of_filter_index>"
  }
  ]
});

フィルター インデックスが設定されたら、 "filter" 句をベクター検索クエリに直接追加できます。 この例では、 "title" プロパティの値が指定されたリストに存在しない結果をフィルター処理する方法を示します。

db.exampleCollection.aggregate([
  {
    '$search': {
      "cosmosSearch": {
        "vector": "<query_vector>",
        "path": <path_to_vector>,
        "k": num_results,
        "filter": {<property_to_filter>: {"$nin": ["not in this text", "or this text"]}}
      },
      "returnStoredSource": True }},
  {'$project': { 'similarityScore': { '$meta': 'searchScore' }, 'document' : '$$ROOT' }
}
]);

Important

事前フィルター処理されたベクター検索のパフォーマンスと精度を最適化するには、ベクター インデックス パラメーターを調整することを検討してください。 DiskANN インデックスの場合、maxDegreeまたはlBuildを増やすと、より良い結果が得られる場合があります。 HNSW インデックスの場合、mefConstruction、またはefSearchの値を大きくして実験すると、パフォーマンスが向上する可能性があります。 同様に、 IVF インデックスの場合、 numLists または nProbes を調整すると、より満足のいく結果が得られます。 データを使用して特定の構成をテストし、結果が要件を満たしていることを確認することが重要です。 これらのパラメーターはインデックス構造と検索動作に影響を与え、最適な値はデータの特性とクエリ パターンによって異なる場合があります。

大規模言語モデル (LLM) オーケストレーション ツールを使用する

セマンティック カーネルでベクトル データベースとして使用する

セマンティック カーネルを使用して、Azure DocumentDB と LLM からの情報取得を調整します。 詳細については、 GitHub リポジトリを参照してください。

LangChain でベクトル データベースとして使用する

LangChain を使用して、Azure DocumentDB と LLM からの情報取得を調整します。 詳細については、「 Azure DocumentDB の LangChain 統合」を参照してください。

LangChain でセマンティック キャッシュとして使用する

LangChain と Azure DocumentDB を使用してセマンティック キャッシュを調整します。以前に記録された LLM 応答を使用すると、LLM API のコストを節約し、応答の待機時間を短縮できます。 詳細については、「 LangChain と Azure DocumentDB の統合」を参照してください。

機能および制限事項

  • サポートされている距離メトリック: L2 (ユークリッド)、内積、コサイン。
  • サポートされているインデックス作成方法: IVFFLAT、HNSW、DiskANN。
  • DiskANN と 製品量子化を使用すると、最大 16,000 次元のベクトルにインデックスを付けることができます。
  • 半精度でHNSWまたはIVFを使用すると、最大4,000次元のベクターのインデックス作成が可能です。
  • 圧縮を使用しない場合、インデックス作成の既定の最大ベクトル 次元は 2,000 です。
  • インデックス作成は、パスごとに 1 つのベクトルにのみ適用されます。
  • ベクター パスごとに作成できるインデックスは 1 つだけです。

概要

このガイドでは、ベクター インデックスの作成、ベクター データを含むドキュメントの追加、類似性検索の実行、インデックス定義の取得を行う方法について説明します。 統合ベクター データベースを使用すると、高次元ベクター データを Azure DocumentDB に直接効率的に格納、インデックス付け、クエリできます。 この機能を使うと、ベクトル埋め込みを使ってデータの可能性を最大限に引き出し、より正確、効率的で強力なアプリケーションを構築できます。

次のステップ