Azure Cosmos DB for MongoDB 仮想コアのベクトル ストア

適用対象: MongoDB 仮想コア

Azure Cosmos DB for MongoDB 仮想コアの統合されたベクター データベースを使用して、AI ベースのアプリケーションと Azure Cosmos DB に格納されているデータをシームレスに接続します。 この統合には、 Azure OpenAI 埋め込みを 使用して構築したアプリを含めることができます。 ネイティブに統合されたベクター データベースを使用すると、Azure Cosmos DB for MongoDB 仮想コアに直接格納される高次元ベクター データを、ベクター データの作成元であるオリジナル データと共に効率的に格納し、インデックス作成やクエリを実行できます。 代替のベクター ストアにデータを転送する必要はなく、追加コストもかかりません。

ベクター ストアとは

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

ベクター ストアのしくみ

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

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

ベクター インデックスを作成する

ドキュメント内のベクトル プロパティ経由でベクトル類似性検索を実行するには、まずベクトル インデックスを作成する必要があります。

HNSW を使用してベクトル インデックスを作成する

M40 クラスター レベル以上で、階層ナビゲーション可能な小さい世界 (HNSW) インデックスを作成できます。 HSNW インデックスを作成するには、以下のテンプレートに従って、"kind" パラメーターを "vector-hnsw" に設定したベクトル インデックスを作成する必要があります。

{ 
    "createIndexes": "<collection_name>",
    "indexes": [
        {
            "name": "<index_name>",
            "key": {
                "<path_to_property>": "cosmosSearch"
            },
            "cosmosSearchOptions": { 
                "kind": "vector-hnsw", 
                "m": <integer_value>, 
                "efConstruction": <integer_value>, 
                "similarity": "<string_value>", 
                "dimensions": <integer_value> 
            } 
        } 
    ] 
}
フィールド タイプ 説明
index_name string インデックスの一意の名前。
path_to_property string ベクターを含むプロパティへのパス。 このパスには、最上位のプロパティまたはそのプロパティへのドット表記パスを指定できます。 ドット表記パスを使用する場合、すべての非リーフ要素を配列にすることはできません。 ベクトルは、インデックスを作成し、ベクトル検索結果で返すために number[] である必要があります。
kind string 作成するベクター インデックスの種類。 オプションは vector-ivfvector-hnsw です。 vector-ivf はすべてのクラスター レベルで利用可能で、vector-hnsw は M40 クラスター レベル以上で利用できます。
m integer レイヤーあたりの接続の最大数 (既定では 16、最小値は 2、最大値は 100)。 m が高いほど、高次元や高精度の要件を持つデータセットに適しています。
efConstruction integer グラフを構築するための動的候補リストのサイズ (既定では 64、最小値は 4、最大値は 1000)。 efConstruction が高いほど、インデックスの品質と精度が向上しますが、インデックスの作成に必要な時間も長くなります。 efConstruction は少なくとも 2 * m である必要があります
similarity string インデックスで使用する類似性メトリック。 可能なオプションは COS (コサイン距離)、L2 (ユークリッド距離)、または IP (内積)です。
dimensions 整数 (integer) ベクトルの類似性の次元の数。 サポートされている次元の最大数は 2000 です。

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

ベクトル検索を実行するには、cosmosSearch 演算子を使用してクエリの $search 集計パイプライン ステージを使用します。

{
    "$search": {
        "cosmosSearch": {
            "vector": <query_vector>,
            "path": "<path_to_property>",
            "k": <num_results_to_return>,
            "efSearch": <integer_value>
        },
    }
  }
}

フィールド タイプ Description
efSearch integer 検索対象の動的候補リストのサイズ (既定では 40)。 値を大きくすると、速度を犠牲にして再現率が向上します。
k integer 返される結果の数。 efSearch 以下にする必要があります

Note

大きなデータセットで HSNW インデックスを作成すると、Azure Cosmos DB for MongoDB 仮想コア リソースがメモリ不足になったり、データベースで実行されている他の操作のパフォーマンスが制限されたりする可能性があります。 このような問題が発生した場合は、リソースをより高次のクラスター レベルにスケーリングするか、データセットのサイズを小さくすることで軽減できます。

IVF を使用してベクトル インデックスを作成する

反転ファイル (IVF) アルゴリズムを使用してベクトル インデックスを作成するには、次の createIndexes テンプレートを使用し、"kind" パラメーターを "vector-ivf" に設定します。

{
  "createIndexes": "<collection_name>",
  "indexes": [
    {
      "name": "<index_name>",
      "key": {
        "<path_to_property>": "cosmosSearch"
      },
      "cosmosSearchOptions": {
        "kind": "vector-ivf",
        "numLists": <integer_value>,
        "similarity": "<string_value>",
        "dimensions": <integer_value>
      }
    }
  ]
}
フィールド タイプ 説明
index_name string インデックスの一意の名前。
path_to_property string ベクターを含むプロパティへのパス。 このパスには、最上位のプロパティまたはそのプロパティへのドット表記パスを指定できます。 ドット表記パスを使用する場合、すべての非リーフ要素を配列にすることはできません。 ベクトルは、インデックスを作成し、ベクトル検索結果で返すために number[] である必要があります。
kind string 作成するベクター インデックスの種類。 オプションは vector-ivfvector-hnsw です。 vector-ivf はすべてのクラスター レベルで利用可能で、vector-hnsw は M40 クラスター レベル以上で利用できます。
numLists integer この整数は、ベクター データをグループ化するために転置ファイル (IVF) インデックスによって使用されるクラスターの数です。 ドキュメント数が 100 万までの場合は numListsdocumentCount/1000 を、100 万を超える場合は sqrt(documentCount) を設定することをお勧めします。 numLists の値に 1 を使用することは、パフォーマンスが制限されるブルート フォース検索を実行することと同様です。
similarity string インデックスで使用する類似性メトリック。 可能なオプションは COS (コサイン距離)、L2 (ユークリッド距離)、または IP (内積)です。
dimensions 整数 (integer) ベクトルの類似性の次元の数。 サポートされている次元の最大数は 2000 です。

重要

numLists パラメーターを正しく設定することは、適切な精度とパフォーマンスを実現するために重要です。 ドキュメント数が 100 万までの場合は numListsdocumentCount/1000 を、100 万を超える場合は sqrt(documentCount) を設定することをお勧めします。

データベース内の項目の数が増えるにつれて、ベクター検索の待機時間パフォーマンスの向上を実現するために、 numList を大きくするように調整する必要があります。

新しいシナリオを試したり、小さなデモを作成したりする場合は、numLists1 に設定して、すべてのベクトルでブルート フォース検索を実行できます。 これにより、ベクトル検索から最も正確な結果を得られますが、検索速度と待機時間が遅くなる点にご注意ください。 初期設定後は、上記のガイダンスを使用して numLists パラメーターを調整する必要があります。

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

ベクター検索を実行するには、MongoDB クエリで $search 集計パイプライン ステージを使用します。 cosmosSearch インデックスを使用するには、新しい cosmosSearch 演算子を使用します。

{
  {
  "$search": {
    "cosmosSearch": {
        "vector": <query_vector>,
        "path": "<path_to_property>",
        "k": <num_results_to_return>,
      },
      "returnStoredSource": True }},
  {
    "$project": { "<custom_name_for_similarity_score>": {
           "$meta": "searchScore" },
            "document" : "$$ROOT"
        }
  }
}

ベクトル検索で検出されたドキュメントと共に類似度スコア (searchScore) を取得するには、$project 演算子を使用して searchScore を含め、結果でその名前を <custom_name_for_similarity_score> に変更します。 これにより、ドキュメントも入れ子になったオブジェクトとして投影されます。 類似度スコアは、ベクトル インデックスで定義されているメトリックを使用して計算されることに注意してください。

重要

ベクトルは、インデックスを作成するために number[] である必要があります。 double[] などの別の型を使用すると、ドキュメントのインデックスが作成されなくなります。 インデックスのないドキュメントは、ベクトル検索の結果では返されません。

HNSW インデックスを使用した例。

次の例では、ベクターのインデックス作成、ベクター プロパティを持つドキュメントの追加、ベクター検索の実行、インデックス構成の取得を行う方法について説明します。

use test;

db.createCollection("exampleCollection");

db.runCommand({ 
    "createIndexes": "exampleCollection",
    "indexes": [
        {
            "name": "VectorSearchIndex",
            "key": {
                "contentVector": "cosmosSearch"
            },
            "cosmosSearchOptions": { 
                "kind": "vector-hnsw", 
                "m": 16, 
                "efConstruction": 64, 
                "similarity": "COS", 
                "dimensions": 3
            } 
        } 
    ] 
});

このコマンドを使用すると、指定したコレクション exampleCollection に格納されているドキュメントの contentVector プロパティに対して HNSW インデックスが作成されます。 cosmosSearchOptions プロパティは、HNSW ベクター インデックスのパラメーターを指定します。 入れ子になったプロパティに格納されているベクターがドキュメントに含まれている場合は、ドット表記パスを使用してこのプロパティを設定できます。 たとえば、contentVectortext のサブプロパティである場合、text.contentVector を使用できます。

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

データベースのコレクションにベクトルを追加するには、最初に、独自のモデル、Azure OpenAI 埋め込み、または別の API (Hugging Face on Azure など) を使って埋め込みを作成する必要があります。 この例では、サンプル埋め込みを使用して新しいドキュメントが追加されます。

db.exampleCollection.insertMany([
  {name: "Eugenia Lopez", bio: "Eugenia is the CEO of AdvenureWorks.", vectorContent: [0.51, 0.12, 0.23]},
  {name: "Cameron Baker", bio: "Cameron Baker CFO of AdvenureWorks.", vectorContent: [0.55, 0.89, 0.44]},
  {name: "Jessie Irwin", bio: "Jessie Irwin is the former CEO of AdventureWorks and now the director of the Our Planet initiative.", vectorContent: [0.13, 0.92, 0.85]},
  {name: "Rory Nguyen", bio: "Rory Nguyen is the founder of AdventureWorks and the president of the Our Planet initiative.", vectorContent: [0.91, 0.76, 0.83]},
]);

最後の例を続けて、別のベクター queryVector を作成します。 ベクター検索では、queryVector とドキュメントの contentVector パス内のベクトル間の距離が測定されます。 パラメーター k (ここでは 2 に設定されています) を設定することで、検索から返される結果の数を設定できます。 また、候補ベクトル リストのサイズを制御する整数である efSearch を設定することもできます。 値を大きくすると精度が向上する可能性があります。ただし、結果として検索が遅くなります。 これは省略可能なパラメーターで、既定値は 40 です。

const queryVector = [0.52, 0.28, 0.12];
db.exampleCollection.aggregate([
  {
    "$search": {
        "cosmosSearch": {
            "vector": "queryVector",
            "path": "contentVector",
            "k": 2,
            "efSearch": 40
        },
    }
  }
}
]);

この例では、Mongo シェルを介した入力として queryVector を使用して、ベクター検索が実行されます。 検索結果は、クエリ ベクターと最も類似している 2 つの項目の一覧で、類似性スコアによって並べ替えられています。

[
  {
    similarityScore: 0.9465376,
    document: {
      _id: ObjectId("645acb54413be5502badff94"),
      name: 'Eugenia Lopez',
      bio: 'Eugenia is the CEO of AdvenureWorks.',
      vectorContent: [ 0.51, 0.12, 0.23 ]
    }
  },
  {
    similarityScore: 0.9006955,
    document: {
      _id: ObjectId("645acb54413be5502badff97"),
      name: 'Rory Nguyen',
      bio: 'Rory Nguyen is the founder of AdventureWorks and the president of the Our Planet initiative.',
      vectorContent: [ 0.91, 0.76, 0.83 ]
    }
  }
]

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

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

db.exampleCollection.getIndexes();

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

[
  { v: 2, key: { _id: 1 }, name: '_id_', ns: 'test.exampleCollection' },
  {
    v: 2,
    key: { contentVector: 'cosmosSearch' },
    name: 'vectorSearchIndex',
    cosmosSearch: {
      kind: 'vector-hnsw',
      m: 40,
      efConstruction: 64
      similarity: 'COS',
      dimensions: 3
    },
    ns: 'test.exampleCollection'
  }
]

IVF インデックスを使用した例

次の例では、ベクターのインデックス作成、ベクター プロパティを持つドキュメントの追加、ベクター検索の実行、インデックス構成の取得を行う方法について説明します。

ベクター インデックスを作成する

use test;

db.createCollection("exampleCollection");

db.runCommand({
  createIndexes: 'exampleCollection',
  indexes: [
    {
      name: 'vectorSearchIndex',
      key: {
        "vectorContent": "cosmosSearch"
      },
      cosmosSearchOptions: {
        kind: 'vector-ivf',
        numLists: 3,
        similarity: 'COS',
        dimensions: 3
      }
    }
  ]
});

このコマンドを使用すると、指定したコレクション exampleCollection に格納されているドキュメントの vectorContent プロパティに対して vector-ivf インデックスが作成されます。 cosmosSearchOptions プロパティは、IVF ベクター インデックスのパラメーターを指定します。 入れ子になったプロパティに格納されているベクターがドキュメントに含まれている場合は、ドット表記パスを使用してこのプロパティを設定できます。 たとえば、vectorContenttext のサブプロパティである場合、text.vectorContent を使用できます。

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

データベースのコレクションにベクトルを追加するには、最初に、独自のモデル、Azure OpenAI 埋め込み、または別の API (Hugging Face on Azure など) を使って埋め込みを作成する必要があります。 この例では、サンプル埋め込みを使用して新しいドキュメントが追加されます。

db.exampleCollection.insertMany([
  {name: "Eugenia Lopez", bio: "Eugenia is the CEO of AdvenureWorks.", vectorContent: [0.51, 0.12, 0.23]},
  {name: "Cameron Baker", bio: "Cameron Baker CFO of AdvenureWorks.", vectorContent: [0.55, 0.89, 0.44]},
  {name: "Jessie Irwin", bio: "Jessie Irwin is the former CEO of AdventureWorks and now the director of the Our Planet initiative.", vectorContent: [0.13, 0.92, 0.85]},
  {name: "Rory Nguyen", bio: "Rory Nguyen is the founder of AdventureWorks and the president of the Our Planet initiative.", vectorContent: [0.91, 0.76, 0.83]},
]);

ベクター検索を実行する

ベクター検索を実行するには、MongoDB クエリで $search 集計パイプライン ステージを使用します。 cosmosSearch インデックスを使用するには、新しい cosmosSearch 演算子を使用します。

{
  {
  "$search": {
    "cosmosSearch": {
        "vector": <vector_to_search>,
        "path": "<path_to_property>",
        "k": <num_results_to_return>,
      },
      "returnStoredSource": True }},
  {
    "$project": { "<custom_name_for_similarity_score>": {
           "$meta": "searchScore" },
            "document" : "$$ROOT"
        }
  }
}

ベクトル検索で検出されたドキュメントと共に類似度スコア (searchScore) を取得するには、$project 演算子を使用して searchScore を含め、結果でその名前を <custom_name_for_similarity_score> に変更します。 これにより、ドキュメントも入れ子になったオブジェクトとして投影されます。 類似度スコアは、ベクトル インデックスで定義されているメトリックを使用して計算されることに注意してください。

最後の例を続けて、別のベクター queryVector を作成します。 ベクター検索では、queryVector とドキュメントの vectorContent パス内のベクトル間の距離が測定されます。 パラメーター k (ここでは 2 に設定されています) を設定することで、検索から返される結果の数を設定できます。 また、各検索で検査される近くのクラスターの数を制御する整数である nProbes を設定することもできます。 値を大きくすると精度が向上する可能性があります。ただし、結果として検索が遅くなります。 これは省略可能なパラメーターで、既定値は 1 であり、ベクター インデックスで指定された numLists 値より大きくすることはできません。

const queryVector = [0.52, 0.28, 0.12];
db.exampleCollection.aggregate([
  {
    $search: {
      "cosmosSearch": {
        "vector": queryVector,
        "path": "vectorContent",
        "k": 2
      },
    "returnStoredSource": true }},
  {
    "$project": { "similarityScore": {
           "$meta": "searchScore" },
            "document" : "$$ROOT"
        }
  }
]);

この例では、Mongo シェルを介した入力として queryVector を使用して、ベクター検索が実行されます。 検索結果は、クエリ ベクターと最も類似している 2 つの項目の一覧で、類似性スコアによって並べ替えられています。

[
  {
    similarityScore: 0.9465376,
    document: {
      _id: ObjectId("645acb54413be5502badff94"),
      name: 'Eugenia Lopez',
      bio: 'Eugenia is the CEO of AdvenureWorks.',
      vectorContent: [ 0.51, 0.12, 0.23 ]
    }
  },
  {
    similarityScore: 0.9006955,
    document: {
      _id: ObjectId("645acb54413be5502badff97"),
      name: 'Rory Nguyen',
      bio: 'Rory Nguyen is the founder of AdventureWorks and the president of the Our Planet initiative.',
      vectorContent: [ 0.91, 0.76, 0.83 ]
    }
  }
]

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

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

db.exampleCollection.getIndexes();

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

[
  { v: 2, key: { _id: 1 }, name: '_id_', ns: 'test.exampleCollection' },
  {
    v: 2,
    key: { vectorContent: 'cosmosSearch' },
    name: 'vectorSearchIndex',
    cosmosSearch: {
      kind: 'vector-ivf',
      numLists: 3,
      similarity: 'COS',
      dimensions: 3
    },
    ns: 'test.exampleCollection'
  }
]

フィルター選択されたベクトル検索 (プレビュー)

$lt$lte$eq$neq$gte$gt$in$nin$regex など、サポートされているクエリ フィルターを使用して、ベクトル検索を実行できるようになりました。 Azure サブスクリプションの [プレビュー機能] タブで、[ベクトル検索のフィルター選択] 機能を有効にします。 プレビュー機能の詳細については、こちらを参照してください。

まず、ベクトルのインデックスとフィルターのインデックスを定義する必要があります。 たとえば、プロパティでフィルター インデックスを定義できます

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

次に、以下に示すように "filter" の用語をベクトル検索に追加します。 この例では、フィルターは、"title" プロパティが ["not in this text", "or this text"] の一覧にないドキュメントを検索しています。


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' }
}
]);

重要

プレビュー段階では、フィルター選択されたベクトル検索では、精度を高めるためにベクトル インデックス パラメーターを調整する必要がある場合があります。 たとえば、HNSW を使用する場合は mefConstructionefSearch を増やし、IVF を使用する場合は numLists または nProbes を増やすことで、より良い結果が得られる可能性があります。 使用前に構成をテストし、満足のいく結果が得られることを確認する必要があります。

LLM オーケストレーション ツールを使用する

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

セマンティック カーネルを使用して、Azure Cosmos DB for MongoDB 仮想コアと LLM からの情報取得を調整できます。 こちらをご覧ください。

https://github.com/microsoft/semantic-kernel/tree/main/python/semantic_kernel/connectors/memory/azure_cosmosdb

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

LangChain を使用して、Azure Cosmos DB for MongoDB 仮想コアと LLM からの情報取得を調整できます。 こちらをご覧ください。

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

LangChain と Azure Cosmos DB for MongoDB (仮想コア) を使用して、セマンティック キャッシュをオーケストレーションし、LLM API のコストを削減し、応答の待機時間を低減することができます。 詳細はこちら

機能および制限事項

  • サポートされている距離メトリック: L2 (ユークリッド)、内積、コサイン。
  • サポートされているインデックス作成方法: IVFFLAT (GA)、HSNW (プレビュー)
  • 最大 2,000 次元のサイズのインデックス作成ベクター。
  • インデックス作成は、パスごとに 1 つのベクトルにのみ適用されます。
  • ベクトル パスごとに作成できるインデックスは 1 つだけです。

まとめ

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

次のステップ