跳到主要内容

MongoDB Atlas

MongoDB Atlas は、AWS、Azure、GCP で利用できる フルマネージドのクラウドデータベースです。MongoDB のドキュメントデータに対する ネイティブな Vector Search と全文検索(BM25 アルゴリズム)をサポートしています。

Atlas Vector Search 機能を使うと、埋め込みを MongoDB ドキュメントに保存し、ベクトル検索インデックスを作成し、 Hierarchical Navigable Small Worlds と呼ばれる近似最近傍アルゴリズムで KNN 検索を実行できます。 LangChain4j の MongoDB 統合は、内部的に $vectorSearch 集約ステージを使用して Atlas Vector Search を実装しています。

LangChain4j と組み合わせて Atlas Vector Search を使い、データに対するセマンティック検索を行い、 シンプルな RAG 実装を構築できます。これらの作業を行う完全なチュートリアルについては、 MongoDB Atlas ドキュメントの Get Started with the LangChain4j Integration チュートリアルを参照してください。

前提条件

Atlas Vector Search を使用するには、デプロイメントで次のいずれかの MongoDB Server バージョンが 稼働している必要があります。

  • 6.0.11 以降
  • 7.0.2 以降

MongoDB は永久無料のクラスターを提供しています。アカウントの設定とデプロイメントへの接続について 詳しくは、Get Started with Atlas チュートリアルを参照してください。

また、埋め込みモデルを提供する LLM サービス(例: Voyage AI、無料枠あり)のクレジット付き API キーも必要です。 RAG アプリケーションでは、チャットモデル機能を持つサービス(例: OpenAIHuggingFace のモデル)の API キーも必要です。

環境とインストール

  1. お好みの IDE で新しい Java アプリケーションを作成します。
  2. LangChain4j と MongoDB Java Sync Driver をインストールするため、 次の依存関係をアプリケーションに追加します。
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-mongodb-atlas</artifactId>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-sync</artifactId>
<version>5.4.0</version>
</dependency>

埋め込みモデル用の依存関係もインストールする必要があります。例として Voyage AI:

<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-voyage-ai</artifactId>
</dependency>

LangChain4j BOM の追加も推奨します:

<dependencyManagement>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-bom</artifactId>
<version>1.18.1-beta28</version>
<type>pom</type>
</dependency>
</dependencyManagement>

MongoDB Atlas を Embedding Store として使う

  1. 埋め込みモデルをインスタンス化します。
  2. MongoDB Atlas を埋め込みストアとしてインスタンス化します。

MongoDbEmbeddingStore インスタンスをビルドする際、createIndex() メソッドに true を渡すと、 自動インデックス作成を有効にできます。

import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import dev.langchain4j.data.document.Metadata;
import dev.langchain4j.data.embedding.Embedding;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.model.voyageai.VoyageAiEmbeddingModel;
import dev.langchain4j.store.embedding.EmbeddingMatch;
import dev.langchain4j.store.embedding.EmbeddingSearchRequest;
import dev.langchain4j.store.embedding.EmbeddingSearchResult;
import dev.langchain4j.store.embedding.filter.comparison.*;
import dev.langchain4j.store.embedding.mongodb.IndexMapping;
import dev.langchain4j.store.embedding.mongodb.MongoDbEmbeddingStore;
import org.bson.Document;

import java.io.*;
import java.util.*;

String embeddingApiKey = System.getenv("VOYAGE_AI_KEY");
String uri = System.getenv("MONGODB_URI");

EmbeddingModel embeddingModel = VoyageAiEmbeddingModel.builder()
.apiKey(embeddingApiKey)
.modelName("voyage-3")
.build();

MongoClient mongoClient = MongoClients.create(uri);

System.out.println("Instantiating the embedding store...");

// Set to false if the vector index already exists
Boolean createIndex = true;

IndexMapping indexMapping = IndexMapping.builder()
.dimension(embeddingModel.dimension())
.metadataFieldNames(new HashSet<>())
.build();

MongoDbEmbeddingStore embeddingStore = MongoDbEmbeddingStore.builder()
.databaseName("search")
.collectionName("langchaintest")
.createIndex(createIndex)
.indexName("vector_index")
.indexMapping(indexMapping)
.fromClient(mongoClient)
.build();

データを MongoDB に保存する

次のコードは、ドキュメントを埋め込みストアに永続化する方法を示します。 embed() メソッドは、ドキュメント内の text フィールド値に対する埋め込みを生成します。

ArrayList<Document> docs = new ArrayList<>();

docs.add(new Document()
.append("text", "Penguins are flightless seabirds that live almost exclusively below the equator. Some island-dwellers can be found in warmer climates.")
.append("metadata", new Metadata(Map.of("website", "Science Direct"))));

docs.add(new Document()
.append("text", "Emperor penguins are amazing birds. They not only survive the Antarctic winter, but they breed during the worst weather conditions on earth.")
.append("metadata", new Metadata(Map.of("website", "Our Earth"))));

docs.add(...);

System.out.println("Persisting document embeddings...");

for (Document doc : docs) {
TextSegment segment = TextSegment.from(
doc.getString("text"),
doc.get("metadata", Metadata.class)
);
Embedding embedding = embeddingModel.embed(segment).content();
embeddingStore.add(embedding, segment);
}

セマンティック / 類似度検索を実行する

次のコードは、クエリをベクトルに変換し、意味的に類似したドキュメントを返す 検索リクエストの作成方法を示します。結果の EmbeddingMatch インスタンスには、 ドキュメント内容と、各結果がクエリにどれだけ一致するかを表すスコアが含まれます。

String query = "Where do penguins live?";
Embedding queryEmbedding = embeddingModel.embed(query).content();

EmbeddingSearchRequest searchRequest = EmbeddingSearchRequest.builder()
.queryEmbedding(queryEmbedding)
.maxResults(3)
.build();

System.out.println("Performing the query...");

EmbeddingSearchResult<TextSegment> searchResult = embeddingStore.search(searchRequest);
List<EmbeddingMatch<TextSegment>> matches = searchResult.matches();

for (EmbeddingMatch<TextSegment> embeddingMatch : matches) {
System.out.println("Response: " + embeddingMatch.embedded().text());
System.out.println("Author: " + embeddingMatch.embedded().metadata().getString("author"));
System.out.println("Score: " + embeddingMatch.score());
}

メタデータフィルタリング

EmbeddingSearchRequest をビルドする際に filter() メソッドを使うと、 メタデータフィルタリングを実装できます。filter() メソッドは Filter を継承するパラメータを受け取ります。

次のコードは、website の値がリスト内のいずれかであるドキュメントのみを対象とする メタデータフィルタリングを実装しています。

EmbeddingSearchRequest searchRequest = EmbeddingSearchRequest.builder()
.queryEmbedding(queryEmbedding)
.filter(new IsIn("website", List.of("Our Earth", "Natural Habitats")))
.maxResults(3)
.build();

RAG

MongoDB Atlas をベクトルストアとして RAG を実装する手順については、Atlas ドキュメント内の LangChain4j チュートリアルの Use Your Data to Answer Questions セクションを参照してください。

API ドキュメント

参考リンク