Docs Menu
Docs Home
/
MongoDB Atlas
/ /

Build a Local RAG Implementation with Atlas Vector Search

On this page

  • Background
  • Prerequisites
  • Create a Local Atlas Deployment
  • Set Up the Environment
  • Generate Embeddings with a Local Model
  • Create the Atlas Vector Search Index
  • Answer Questions with a Local LLM

This tutorial demonstrates how to implement retrieval-augmented generation (RAG) locally, without the need for API keys or credits. To learn more about RAG, see Retrieval-Augmented Generation (RAG) with Atlas Vector Search.

Specifically, you perform the following actions:

  1. Create a local Atlas deployment.

  2. Set up the environment.

  3. Use a local embedding model to generate vector embeddings.

  4. Create an Atlas Vector Search index on your data.

  5. Deploy a local LLM to answer questions on your data.

To complete this tutorial, you can either create a local Atlas deployment by using the Atlas CLI or deploy a cluster on the cloud. The Atlas CLI is the command-line interface for MongoDB Atlas, and you can use the Atlas CLI to interact with Atlas from the terminal for various tasks, including creating local Atlas deployments. To learn more, see Manage Local and Cloud Deployments from the Atlas CLI.

Note

Local Atlas deployments are intended for testing only. For production environments, deploy a cluster.

You also use the following open-source models in this tutorial:

There are several ways to download and deploy LLMs locally. In this tutorial, you download the Mistral 7B model by using GPT4All, an open-source ecosystem for local LLM development.

This tutorial also uses LangChain, a popular open-source LLM framework, to connect to these models and integrate them with Atlas Vector Search. If you prefer different models or a different framework, you can adapt this tutorial by replacing the model names and LangChain-specific components with their equivalents for your preferred setup.

To learn more about how to leverage LangChain in your RAG applications, see Get Started with the LangChain Integration. To learn more about other frameworks you can use with Atlas Vector Search, see Integrate Vector Search with AI Technologies.

To complete this tutorial, you must have the following:

  • The Atlas CLI installed and running v1.14.3 or later.

  • An interactive Python notebook that you can run locally. You can run interactive Python notebooks in VS Code. Ensure that your environment runs Python v3.10 or later.

    Note

    If you use a hosted service such as Colab, ensure that you have enough RAM to run this tutorial. Otherwise, you might experience performance issues.

In this section, you create a local Atlas deployment to use as a vector database. If you have an Atlas cluster running MongoDB version 6.0.11, 7.0.2, or later with the sample data loaded, you can skip this step.

To create the local deployment:

1

In your terminal, run atlas auth login to authenticate with your Atlas login credentials. To learn more, see Connect from the Atlas CLI.

Note

If you don't have an existing Atlas account, run atlas setup or create a new account.

2

Run atlas deployments setup and follow the prompts to create a local deployment.

For detailed instructions, see Create a Local Atlas Deployment.

3
  1. Run the following command in your terminal to download the sample data:

    curl https://atlas-education.s3.amazonaws.com/sampledata.archive -o sampledata.archive
  2. Run the following command to load the data into your deployment, replacing <port-number> with the port where you're hosting the deployment:

    mongorestore --archive=sampledata.archive --port=<port-number>

In this section, you set up the environment for this tutorial. Create an interactive Python notebook by saving a file with the .ipynb extension, and then run the following code snippets in the notebook.

1

Run the following command:

pip install --quiet langchain langchain_community langchain_huggingface langchain-mongodb pymongo sentence-transformers gpt4all
2

If you're using a local Atlas deployment, run the following code in your notebook, replacing <port-number> with the port for your local deployment.

ATLAS_CONNECTION_STRING = ("mongodb://localhost:<port-number>/?directConnection=true")

If you're using an Atlas cluster, run the following code in your notebook, replacing <connection-string> with your Atlas cluster's SRV connection string:

ATLAS_CONNECTION_STRING = ("<connection-string>")

Note

Your connection string should use the following format:

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

In this section, you load an embedding model locally and create vector embeddings using data from the sample_airbnb database, which contains a single collection called listingsAndReviews. The following code snippet performs the following actions:

  • Establishes a connection to your local Atlas deployment or your Atlas cluster and the sample_airbnb.listingsAndReviews collection.

  • Loads the bge-large-en-v1.5 embedding model from LangChain's HuggingFaceEmbeddings library.

  • Creates a filter to include only documents that have a summary field and don't have an embeddings field.

  • For each document in the collection that satisfies the filter:

    • Generates an embedding from the document's summary field by using the bge-large-en-v1.5 embedding model.

    • Updates the document by creating a new field called embeddings that contains the embedding.

Run the following code in your notebook:

from langchain_huggingface import HuggingFaceEmbeddings
from pymongo import MongoClient
# Connect to your local Atlas deployment or Atlas Cluster
client = MongoClient(ATLAS_CONNECTION_STRING)
# Select the sample_airbnb.listingsAndReviews collection
collection = client["sample_airbnb"]["listingsAndReviews"]
# Specify local embedding model (https://huggingface.co/sentence-transformers/baai/bge-large-en-v1.5)
model = HuggingFaceEmbeddings(model_name="baai/bge-large-en-v1.5")
# Filters for only documents with a summary field and without an embeddings field
filter = { '$and': [ { 'summary': { '$exists': True, '$ne': None } }, { 'embeddings': { '$exists': False } } ] }
count = 0
totalCount = collection.count_documents(filter)
# Creates embeddings and updates the documents in the collection
for document in collection.find(filter):
text = document['summary']
embedding = model.embed_query(text)
collection.update_one({ '_id': document['_id'] }, { "$set": { 'embeddings': embedding } }, upsert = True)
count+=1
print("Documents updated: {}/{} ".format(count, totalCount))

This code takes some time to run. After it's finished, you can connect to your local deployment from mongosh or your application by using your deployment's connection string. Then, to view your vector embeddings, run read operations on the sample_airbnb.listingsAndReviews collection.

This code takes some time to run. After it's finished, you can view your vector embeddings in the Atlas UI by navigating to the sample_airbnb.listingsAndReviews collection in your cluster and expanding the fields in a document.

To enable vector search on the sample_airbnb.listingsAndReviews collection, create an Atlas Vector Search index.

If you're using a local Atlas deployment, complete the following steps:

1

Create a file named vector-index.json and paste the following index definition in the file.

This index definition specifies indexing the embeddings field in an index of the vectorSearch type for the sample_airbnb.listingsAndReviews collection. This field contains the embeddings created using the bge-large-en-v1.5 embedding model. The index definition specifies 1024 vector dimensions and measures similarity using cosine.

{
"database": "sample_airbnb",
"collectionName": "listingsAndReviews",
"type": "vectorSearch",
"name": "vector_index",
"fields": [
{
"type": "vector",
"path": "embeddings",
"numDimensions": 1024,
"similarity": "cosine"
}
]
}
2
  1. Save the file, and then run the following command in your terminal, replacing <path-to-file> with the path to the vector-index.json file that you created.

    atlas deployments search indexes create --file <path-to-file>

Note

To create an Atlas Vector Search index, you must have Project Data Access Admin or higher access to the Atlas project.

If you're using an Atlas cluster, complete the following steps:

1
  1. If it's not already displayed, select the organization that contains your desired project from the Organizations menu in the navigation bar.

  2. If it's not already displayed, select your desired project from the Projects menu in the navigation bar.

  3. If the Clusters page is not already displayed, click Database in the sidebar.

    The Clusters page displays.

2

You can go the Atlas Search page from the sidebar, the Data Explorer, or your cluster details page.

  1. In the sidebar, click Atlas Search under the Services heading.

  2. From the Select data source dropdown, select your cluster and click Go to Atlas Search.

    The Atlas Search page displays.

  1. Click the Browse Collections button for your cluster.

  2. Expand the database and select the collection.

  3. Click the Search Indexes tab for the collection.

    The Atlas Search page displays.

  1. Click the cluster's name.

  2. Click the Atlas Search tab.

    The Atlas Search page displays.

3
  1. Click Create Search Index.

  2. Under Atlas Vector Search, select JSON Editor and then click Next.

  3. In the Database and Collection section, find the sample_airbnb database, and select the listingsAndReviews collection.

  4. In the Index Name field, enter vector_index.

  5. Replace the default definition with the following index definition and then click Next.

    This index definition specifies indexing the embeddings field in an index of the vectorSearch type for the sample_airbnb.listingsAndReviews collection. This field contains the embeddings created using the bge-large-en-v1.5 embedding model. The index definition specifies 1024 vector dimensions and measures similarity using cosine.

    {
    "fields":[
    {
    "type": "vector",
    "path": "embeddings",
    "numDimensions": 1024,
    "similarity": "cosine"
    }
    ]
    }
4

A modal window displays to let you know that your index is building.

5

The index should take about one minute to build. While it builds, the Status column reads Initial Sync. When it finishes building, the Status column reads Active.

This section demonstrates a sample RAG implementation that you can run locally by using Atlas Vector Search, LangChain, and GPT4All. In your interactive Python notebook, run the following code snippets:

1

The following code uses the LangChain integration for Atlas Vector Search to instantiate your local Atlas deployment or your Atlas cluster as a vector database, also called a vector store.

from langchain_mongodb import MongoDBAtlasVectorSearch
# Instantiate vector store
vector_store = MongoDBAtlasVectorSearch(
collection=collection,
embedding=model,
index_name="vector_index",
embedding_key="embeddings",
text_key="summary")

You can also run the following code to execute a sample semantic search query:

import pprint
query = "beach house"
results = vector_store.similarity_search(query)
pprint.pprint(results)
[Document(page_content='Beach house with contemporary interior', metadata={'_id': '22123688', 'listing_url': 'https://www.airbnb.com/rooms/22123688', 'name': 'Bungan Beach House', ... }),
Document(page_content="Well done !!! you won't find a better location in Manly. The “Beach House” Apartments overlook Cabbage Tree Bay Aquatic Reserve between Manly and Shelly Beach, in one of Manly's premier locations Swim, dive, snorkel, surf, paddle board, coastal walkways, ocean pool, restaurants, all literally at your doorstep, or simply chill and unwind. Manly is amazing, I look forward to welcoming you", metadata={'_id': '18917022', 'listing_url': 'https://www.airbnb.com/rooms/18917022', 'name': 'Beach House Manly Apartment 4', ... }]}),
Document(page_content='Beautiful spacious two story beach house that has an amazing private gated grass area fronting Makaha beach. Perfect for family BBQ,s while watching the sun set into the ocean. Room for 10 people. Four night minimum stay required', metadata={'_id': '7099038', 'listing_url': 'https://www.airbnb.com/rooms/7099038', 'name': 'Ocean front Beach House in Makaha', ... }]}),
Document(page_content='Beautifully finished, newly renovated house with pool. The ultimate in indoor/outdoor living. Excellent finishes and a short stroll to the beach.', metadata={'_id': '19768051', 'listing_url': 'https://www.airbnb.com/rooms/19768051', 'name': 'Ultra Modern Pool House Maroubra', ... }]})]

Tip

See also:

2
  1. Click the following button to download the Mistral 7B model from GPT4All. To explore other models, refer to the GPT4All website.

    Download
  2. Paste the following code in your notebook to configure the LLM. Before running, replace <path-to-model> with the path where you saved the LLM locally.

    from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler
    from langchain_community.llms import GPT4All
    # Configure the LLM
    local_path = "<path-to-model>"
    # Callbacks support token-wise streaming
    callbacks = [StreamingStdOutCallbackHandler()]
    # Verbose is required to pass to the callback manager
    llm = GPT4All(model=local_path, callbacks=callbacks, verbose=True)
3

Run the following code to complete your RAG implementation. This code does the following:

  • Instantiates Atlas Vector Search as a retriever to query for similar documents.

  • Creates the following LangChain-specific components:

    • A prompt template to instruct the LLM to use the retrieved documents as context for your query. LangChain passes these documents to the {context} input variable and your query to the {question} variable.

    • A chain that specifies Atlas Vector Search as the retriever, the prompt template that you wrote, and the local LLM that you configured to generate a context-aware response.

  • Prompts the LLM with a sample query and returns the response. The generated response might vary.

from langchain_core.prompts import PromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
# Instantiate Atlas Vector Search as a retriever
retriever = vector_store.as_retriever()
# Define prompt template
template = """
Use the following pieces of context to answer the question at the end.
{context}
Question: {question}
"""
custom_rag_prompt = PromptTemplate.from_template(template)
def format_docs(docs):
return "\n\n".join(doc.page_content for doc in docs)
# Create chain
rag_chain = (
{"context": retriever | format_docs, "question": RunnablePassthrough()}
| custom_rag_prompt
| llm
| StrOutputParser()
)
# Prompt the chain
question = "Can you recommend me a few AirBnBs that are beach houses? Include a link to the listings."
answer = rag_chain.invoke(question)
# Return source documents
documents = retriever.invoke(question)
print("\nSource documents:")
pprint.pprint(documents)
Answer: Yes, I can recommend a few AirBnBs that are beach houses. Here are some links to their respective listings:
1. Oceanfront home on private, gated property - https://www.airbnb.com/rooms/15073739
2. Ground Floor, Oceanfront condo with complete remodeling - https://www.airbnb.com/rooms/14687148
3. 4 bedroom house in a great location with ocean views and free salt water pool - https://www.airbnb.ca/s?host_id=740644
Source documents:
[Document(page_content='Please look for Airbnb numb (Phone number hidden by Airbnb) to book with us. We do not take bookings through this one. It is live for others to read reviews. Oceanfront home on private, gated property. This unique property offers year-round swimming, private beach access and astounding ocean and mountain views. Traveling with a large group? Another 3 bedroom home is available for rent on this spacious property. Visit https://www.airbnb.com/rooms/15073739 or contact us for more information.', metadata={'_id': '14827972', 'listing_url': 'https://www.airbnb.com/rooms/14827972', 'name': 'Oceanfront Beach House Makai', ... }]}),
Document(page_content='This GROUND FLOOR, OCEANFRONT condo is just feet from ocean access. Completely remodeled kitchen, bathroom and living room, with queen size bed in the bedroom, and queen size convertible sofa bed in the living room. Relax with the 55" SMART blue ray DVD, cable, and free WiFi. With ceiling fans in each room and trade winds, this condo rarely need the air conditioning unit in the living room. Airbnb charges a reservation fee to all guests at the time of booking. Please see "Other Things to Note"', metadata={'_id': '18173803', 'listing_url': 'https://www.airbnb.com/rooms/18173803', 'name': 'Papakea A108', ... }]}),
Document(page_content='2 minutes to bus stop, beach - Cafes, Sun, Surf & Sand. 4 Secure rooms in older style, 4 bedroom house. Can squeeze in up to 15 guests (9 beds, 2 sofa beds in lounge & a single sofa mattress) BUT is best suited to 10-12 people Wireless Internet, under cover parking, unlimited street parking.', metadata={'_id': '2161945', 'listing_url': 'https://www.airbnb.com/rooms/2161945', 'name': 'Sand Sun Surf w Parking. City 9km', ... }]}),
Document(page_content='High Quality for a third of the price! Great Location & Ocean Views! FREE Salt Water Roof-Deck Pool, Activities & Rental Car Desk! Hassle-Free Self Check-In via Lockbox. Located In Famous Waikiki: Easily walk to Beaches, Shops/all Restaurants! Hawaiian Convention Center is only 2 Blocks Away! On-Site Garage $. See my similar listings if your dates are not available. https://www.airbnb.ca/s?host_id=740644', metadata={'_id': '13146333', 'listing_url': 'https://www.airbnb.com/rooms/13146333', 'name': '~TROPICAL DREAM VACATION~ Ocean View', ... }]})]

Back

Hybrid Search

Next

AI Integrations