Docs Menu
Docs Home
/
Atlas
/ / /

MongoDBと Lgachein で自己クエリ検索を実行

MongoDB ベクトル検索 をLgChuin と統合すると、 の自己クエリ検索を実行できます。このチュートリアルでは、自己クエリリトリバーを使用して、メタデータをフィルタリングして自然言語MongoDB ベクトル検索クエリを実行する方法を説明します。

セルフクエリ検索では、LVM を使用して検索クエリーを処理し、可能なメタデータフィルターを識別し、フィルターを使用して構造化ベクトル検索クエリーを作成し、そのクエリを実行して最も関連性の高いドキュメントを検索します。

「評価が を超える、 以降のアクション映画は?クエリに一致するドキュメントを検索するためにフィルタリングします。20108genreyearrating

このチュートリアルの実行可能なバージョンを Python エディタとして操作します。

Atlas の サンプル データ セット からの映画データを含むコレクションを使用します。

  • 次のいずれかのMongoDBクラスター タイプ

    • MongoDBバージョン 6.0.11を実行中Atlas クラスター7.0.2、またはそれ以降IPアドレスが Atlas プロジェクトのアクセス リストに含まれていることを確認します。

    • Atlas CLI を使用して作成されたローカル Atlas 配置。詳細については、「Atlas 配置のローカル配置の作成」を参照してください。

    • Search とベクトル検索がインストールされたMongoDB Community または Enterprise クラスター。

  • 投票AI APIキー。詳細については、投票AIドキュメント を参照してください

  • OpenAI APIキー。APIリクエストに使用できるクレジットを持つ OpenAI アカウントが必要です。OpenAI アカウントの登録の詳細については、OpenAI APIウェブサイト を参照してください。

このセクションでは、 MongoDBクラスターをベクトルデータベースとして使用してベクトルストアのインスタンスを作成します。

1

このチュートリアルの環境を設定します。 .ipynb 拡張機能のファイルを保存して、インタラクティブPythonノートを作成します。 このノートはPythonコード スニペットを個別に実行でき、このチュートリアルのコードを実行するために使用します。

ノートク環境を設定するには、次の手順に従います。

  1. ノートブックで次のコマンドを実行します。

    pip install --quiet --upgrade langchain-mongodb langchain-voyageai langchain-openai langchain langchain-core lark
  2. 環境変数を設定してください。

    このチュートリアルの環境変数を設定するには、次のコードを実行します。Vorage APIキー、OpenAI APIキー、およびMongoDBクラスターの SRV 接続文字列を指定します。

    import os
    os.environ["OPENAI_API_KEY"] = "<openai-key>"
    os.environ["VOYAGE_API_KEY"] = "<voyage-key>"
    MONGODB_URI = "<connection-string>"

    注意

    <connection-string> を Atlas クラスターまたはローカル Atlas 配置の接続文字列に置き換えます。

    接続stringには、次の形式を使用する必要があります。

    mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net

    詳しくは、ドライバーを使用してクラスターに接続する を参照してください。

    接続stringには、次の形式を使用する必要があります。

    mongodb://localhost:<port-number>/?directConnection=true

    詳細については、「接続文字列 」を参照してください。

2

ノート次のコードを実行して、 MongoDBの langchain_db.self_query名前空間を使用して vector_store という名前のベクトルストアインスタンスを作成します。

from langchain_mongodb import MongoDBAtlasVectorSearch
from langchain_voyageai import VoyageAIEmbeddings
# Use the voyage-3-large embedding model
embedding_model = VoyageAIEmbeddings(model="voyage-3-large")
# Create the vector store
vector_store = MongoDBAtlasVectorSearch.from_connection_string(
connection_string = MONGODB_URI,
embedding = embedding_model,
namespace = "langchain_db.self_query",
text_key = "page_content"
)
3

ノートクに次のコードを貼り付けて実行し、メタデータを含むサンプルドキュメントをMongoDBのコレクションに取り込みます。

from langchain_core.documents import Document
docs = [
Document(
page_content="A bunch of scientists bring back dinosaurs and mayhem breaks loose",
metadata={"year": 1993, "rating": 7.7, "genre": "action"},
),
Document(
page_content="A fight club that is not a fight club, but is a fight club",
metadata={"year": 1994, "rating": 8.7, "genre": "action"},
),
Document(
page_content="Leo DiCaprio gets lost in a dream within a dream within a dream within a ...",
metadata={"year": 2010, "genre": "thriller", "rating": 8.2},
),
Document(
page_content="A bunch of normal-sized women are supremely wholesome and some men pine after them",
metadata={"year": 2019, "rating": 8.3, "genre": "drama"},
),
Document(
page_content="Three men walk into the Zone, three men walk out of the Zone",
metadata={"year": 1979, "rating": 9.9, "genre": "science fiction"},
),
Document(
page_content="A psychologist / detective gets lost in a series of dreams within dreams within dreams and Inception reused the idea",
metadata={"year": 2006, "genre": "thriller", "rating": 9.0},
),
Document(
page_content="Toys come alive and have a blast doing so",
metadata={"year": 1995, "genre": "animated", "rating": 9.3},
),
Document(
page_content="The toys come together to save their friend from a kid who doesn't know how to play with them",
metadata={"year": 1997, "genre": "animated", "rating": 9.1},
),
]
# Add data to the vector store, which automaticaly embeds the documents
vector_store.add_documents(docs)

Atlaslangchain_db.self_query を使用している場合は、Atlas UI で名前空間に移動することでベクトル埋め込みを確認できます。

4

次のコードを実行して、ベクトル検索とデータのメタデータフィルタリングを有効にするためにベクトルストアのフィルターを含むMongoDB ベクトル検索インデックスを作成します。

# Use LangChain helper method to create the vector search index
vector_store.create_vector_search_index(
dimensions = 1024, # The dimensions of the vector embeddings to be indexed
filters = [ "genre", "rating", "year" ], # The metadata fields to be indexed for filtering
wait_until_complete = 60 # Number of seconds to wait for the index to build (can take around a minute)
)

Tip

インデックスの構築には約 1 分かかります。 構築中、インデックスは最初の同期状態になります。 構築が完了したら、コレクション内のデータのクエリを開始できます。

このセクションでは、ベクトルストアのデータをクエリするために自己クエリ レプリカを初期化します。

1

自己クエリ検索バーを使用するには、コレクション内のドキュメントと、フィルタリングするメタデータフィールドを記述する必要があります。この情報は、LM がデータの構造と、ユーザー クエリに基づいて結果をフィルタリングする方法を理解するのに役立ちます。

from langchain.chains.query_constructor.schema import AttributeInfo
# Define the document content description
document_content_description = "Brief summary of a movie"
# Define the metadata fields to filter on
metadata_field_info = [
AttributeInfo(
name="genre",
description="The genre of the movie",
type="string",
),
AttributeInfo(
name="year",
description="The year the movie was released",
type="integer",
),
AttributeInfo(
name="rating",
description="A 1-10 rating for the movie",
type="float"
),
]
2

MongoDBAtlasSelfQueryRetriever.from_llm メソッドを使用して自己クエリ型リゾルバを作成するには、次のコードを実行します。

from langchain_mongodb.retrievers import MongoDBAtlasSelfQueryRetriever
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4o")
retriever = MongoDBAtlasSelfQueryRetriever.from_llm(
llm=llm,
vectorstore=vector_store,
metadata_field_info=metadata_field_info,
document_contents=document_content_description
)

次のクエリを実行して、自己クエリ検索取得者がさまざまなタイプのクエリをどのように実行するかを確認します。

# This example specifies a filter (rating > 9)
retriever.invoke("What are some highly rated movies (above 9)?")
[Document(id='686e84de13668e4048bf9ff3', metadata={'_id': '686e84de13668e4048bf9ff3', 'year': 1979, 'rating': 9.9, 'genre': 'science fiction'}, page_content='Three men walk into the Zone, three men walk out of the Zone'),
Document(id='686e84de13668e4048bf9ff5', metadata={'_id': '686e84de13668e4048bf9ff5', 'year': 1995, 'genre': 'animated', 'rating': 9.3}, page_content='Toys come alive and have a blast doing so'),
Document(id='686e84de13668e4048bf9ff6', metadata={'_id': '686e84de13668e4048bf9ff6', 'year': 1997, 'genre': 'animated', 'rating': 9.1}, page_content="The toys come together to save their friend from a kid who doesn't know how to play with them")]
# This example specifies a semantic search and a filter (rating > 9)
retriever.invoke("I want to watch a movie about toys rated higher than 9")
[Document(id='686e84de13668e4048bf9ff5', metadata={'_id': '686e84de13668e4048bf9ff5', 'year': 1995, 'genre': 'animated', 'rating': 9.3}, page_content='Toys come alive and have a blast doing so'),
Document(id='686e84de13668e4048bf9ff6', metadata={'_id': '686e84de13668e4048bf9ff6', 'year': 1997, 'genre': 'animated', 'rating': 9.1}, page_content="The toys come together to save their friend from a kid who doesn't know how to play with them"),
Document(id='686e84de13668e4048bf9ff3', metadata={'_id': '686e84de13668e4048bf9ff3', 'year': 1979, 'rating': 9.9, 'genre': 'science fiction'}, page_content='Three men walk into the Zone, three men walk out of the Zone')]
# This example specifies a composite filter (rating >= 9 and genre = thriller)
retriever.invoke("What's a highly rated (above or equal 9) thriller film?")
[Document(id='686e84de13668e4048bf9ff4', metadata={'_id': '686e84de13668e4048bf9ff4', 'year': 2006, 'genre': 'thriller', 'rating': 9.0}, page_content='A psychologist / detective gets lost in a series of dreams within dreams within dreams and Inception reused the idea')]
# This example specifies a query and composite filter (year > 1990 and year < 2005 and genre = action)
retriever.invoke(
"What's a movie after 1990 but before 2005 that's all about dinosaurs, " +
"and preferably has the action genre"
)
[Document(id='686e84de13668e4048bf9fef', metadata={'_id': '686e84de13668e4048bf9fef', 'year': 1993, 'rating': 7.7, 'genre': 'action'}, page_content='A bunch of scientists bring back dinosaurs and mayhem breaks loose'),
Document(id='686e84de13668e4048bf9ff0', metadata={'_id': '686e84de13668e4048bf9ff0', 'year': 1994, 'rating': 8.7, 'genre': 'action'}, page_content='A fight club that is not a fight club, but is a fight club')]
# This example only specifies a semantic search query
retriever.invoke("What are some movies about dinosaurs")
[Document(id='686e84de13668e4048bf9fef', metadata={'_id': '686e84de13668e4048bf9fef', 'year': 1993, 'rating': 7.7, 'genre': 'action'}, page_content='A bunch of scientists bring back dinosaurs and mayhem breaks loose'),
Document(id='686e84de13668e4048bf9ff5', metadata={'_id': '686e84de13668e4048bf9ff5', 'year': 1995, 'genre': 'animated', 'rating': 9.3}, page_content='Toys come alive and have a blast doing so'),
Document(id='686e84de13668e4048bf9ff1', metadata={'_id': '686e84de13668e4048bf9ff1', 'year': 2010, 'genre': 'thriller', 'rating': 8.2}, page_content='Leo DiCaprio gets lost in a dream within a dream within a dream within a ...'),
Document(id='686e84de13668e4048bf9ff6', metadata={'_id': '686e84de13668e4048bf9ff6', 'year': 1997, 'genre': 'animated', 'rating': 9.1}, page_content="The toys come together to save their friend from a kid who doesn't know how to play with them")]

自己クエリ型リゾルバは、 RAGパイプラインで使用できます。次のコードをノート PC に貼り付けて実行し、自己クエリ検索を実行するサンプルRAGパイプラインを実装します。

このコードでは、必要に応じて LM が取得で返されるドキュメント数を制限できるようにする enable_limit パラメータを使用するように取得を構成します。 生成される応答は異なる場合があります。

import pprint
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import PromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4o")
# Configure self-query retriever with a document limit
retriever = MongoDBAtlasSelfQueryRetriever.from_llm(
llm,
vector_store,
document_content_description,
metadata_field_info,
enable_limit=True
)
# Define a prompt template
template = """
Use the following pieces of context to answer the question at the end.
{context}
Question: {question}
"""
prompt = PromptTemplate.from_template(template)
# Construct a chain to answer questions on your data
chain = (
{ "context": retriever, "question": RunnablePassthrough()}
| prompt
| llm
| StrOutputParser()
)
# Prompt the chain
question = "What are two movies about toys after 1990?" # year > 1990 and document limit of 2
answer = chain.invoke(question)
print("Question: " + question)
print("Answer: " + answer)
# Return source documents
documents = retriever.invoke(question)
print("\nSource documents:")
pprint.pprint(documents)
Question: What are two movies about toys after 1990?
Answer: The two movies about toys after 1990 are:
1. The 1995 animated movie (rated 9.3) where toys come alive and have fun.
2. The 1997 animated movie (rated 9.1) where toys work together to save their friend from a kid who doesn’t know how to play with them.
Source documents:
[Document(id='686e84de13668e4048bf9ff5', metadata={'_id': '686e84de13668e4048bf9ff5', 'year': 1995, 'genre': 'animated', 'rating': 9.3}, page_content='Toys come alive and have a blast doing so'),
Document(id='686e84de13668e4048bf9ff6', metadata={'_id': '686e84de13668e4048bf9ff6', 'year': 1997, 'genre': 'animated', 'rating': 9.1}, page_content="The toys come together to save their friend from a kid who doesn't know how to play with them")]

戻る

Parent Document Retrieval

項目一覧