Thursday, April 16, 2026

Vector Stores in LangChain With Examples

In the post Embeddings in LangChain With Examples we saw how you can convert your documents into embeddings (high-dimensional vectors) which represent the semantic meaning of the text. Now the next step is where to store these embeddings so that you can later retrieve the relevant documents by doing the semantic search. That’s where vector stores come into picture.

What are Vector Stores

Vector stores are special kind of databases that can store embeddings.

Embeddings in vector store

Unlike traditional databases that search for exact keyword matches, vector stores enable semantic search, that allows applications to retrieve information based on conceptual similarity (similarity search).

Vector Stores in LangChain

How Vector Stores Work

When you query these vector databases, those queries are also converted into high-dimensional vectors. These vector stores use mathematical distance metrics (like Cosine Similarity or Euclidean distance) to find vectors closest to the query vector.

This retrieval is made more efficient by indexing the data in the vector store. Without indexing, similarity search requires a brute force linear scan across millions of vectors, which is computationally expensive.

Indexing in a vector store means organizing high-dimensional embeddings into smart data structures so that searches are fast and efficient. Instead of scanning every vector one by one (which is slow), indexing narrows down the search space. Listed below are some of the algorithms used for indexing.

  • Tree-based structures: break the space into hierarchical partitions.
  • Clustering (IVF – Inverted File Index): group vectors into clusters, then search only the most relevant ones.
  • Graph-based approaches (HNSW – Hierarchical Navigable Small World graphs): connect vectors in a graph so nearest neighbors can be found quickly by traversing edges.

Commonly Used Vector Stores

Here is a list of some of the most commonly used vector stores.

  1. Chroma- Lightweight, open-source vector DB with local persistence and easy LangChain integration.
  2. Pinecone- Fully managed cloud vector database designed for large-scale, production-ready similarity search.
  3. Weaviate- Open-source vector search engine with hybrid search (text + vectors) and schema support.
  4. Milvus- High-performance, distributed vector database optimized for massive datasets.
  5. FAISS- Facebook’s library for efficient similarity search and clustering of dense vectors, often used locally.
  6. Qdrant- Open-source vector DB with focus on high-performance ANN search and filtering.

If you want local development, create a quick prototype local persistence like Chroma, FAISS are good choices. For scalable cloud deployments go with Pinecone, Weaviate, Milvus, Qdrant.

Vector Stores in LangChain

LangChain provides a unified interface for integrating with several vector stores. Common methods are-

  • add_documents- Add documents to the store.
  • delete- Remove stored documents by ID.
  • similarity_search- Query for semantically similar documents.

LangChain provides support for InMemoryVectorStore, Chroma, ElasticsearchStore, FAISS, MongoDBAtlasVectorSearch, PGVectorStore (uses PostgreSQL with the pgvector extension), PineconeVectorStore and many more.

LangChain Vector Store Example

Here is a full-fledged example of loading and splitting the document, creating embeddings and storing it in Chroma vector store.

There is a util class with utility methods to load and split the document.

util.py

from langchain_community.document_loaders import PyPDFLoader, DirectoryLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_ollama import OllamaEmbeddings

def load_documents(dir_path):
    
    """
    loading the documents in a specified directory
    """
    pdf_loader = DirectoryLoader(dir_path, glob="*.pdf", loader_cls=PyPDFLoader)
    documents = pdf_loader.load()
    return documents

def create_splits(extracted_data):
    """
    splitting the document using text splitter
    """
    text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=100)
    text_chunks = text_splitter.split_documents(extracted_data)
    return text_chunks

def getEmbeddingModel():
    """
    Configure the embedding model used
    """
    embeddings = OllamaEmbeddings(model="nomic-embed-text")
    return embeddings

Then there is a dbutil class that uses Chroma DB to store the embeddings.

dbutil.py

from langchain_chroma import Chroma
from util import load_documents, create_splits, getEmbeddingModel

def get_chroma_store():
    embeddings = getEmbeddingModel()
    vector_store = Chroma(
        collection_name="data_collection",
        embedding_function=embeddings,
        persist_directory="./chroma_langchain_db",  # Where to save data locally
    )
    return vector_store

def load_data():
    # Access the underlying Chroma client
    #client = get_chroma_store()._client

    # Delete the collection
    #client.delete_collection("data_collection")

    documents = load_documents("./langchaindemos/resources")
    text_chunks = create_splits(documents)
    vector_store = get_chroma_store()
    #add documents
    vector_store.add_documents(text_chunks)

load_data()

Run this file once to do the process of loading the documents, splitting it and storing the chunks in the DB.

Points to note here-

  1. Needs the langchain_chroma package installation.
  2. Create a chroma client using the Chroma class, parameters passed are the collection name (identifier for where vectors are stored), embedding_function (Embedding class object), persist_directory (directory where your vector database is saved locally).

Once the embeddings are stored in the vector store it can be queried to do a similarity search and return the relevant chunks. I have loaded a health insurance document so queries are related to that document.

chromaapp.py

from langchain_chroma import Chroma
from dbutil import get_chroma_store

vector_store = get_chroma_store()

#search documents
result = vector_store.similarity_search(
  query='What is the waiting period for the pre-existing diseases',
  k=3 # number of outcomes 
)

#displaying the results
for i, res in enumerate(result):
    print(f"Result {i+1}: {res.page_content[:500]}...")
print("Another Query")
query = "What is the condition for getting cumulative bonus"
result = vector_store.similarity_search(query, k=3)

for i, res in enumerate(result):
    print(f"Result {i+1}: {res.page_content[:500]}...")

print("Another Query")
query = "What are the co-pay rules"
result = vector_store.similarity_search(query, k=3)

for i, res in enumerate(result):
    print(f"Result {i+1}: {res.page_content[:500]}...")

Points to note here-

  1. In similarity_search() method, k parameter is used to configure the number of results to return.
  2. similarity_search() method returns the list of documents most similar to the query text.
  3. By looping that list, we can get the content of each result.
    for i, res in enumerate(result):
        print(f"Result {i+1}: {res.page_content[:500]}...")
    

That's all for this topic Vector Stores in LangChain With Examples. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. Document Loaders in LangChain With Examples
  2. Text Splitters in LangChain With Examples
  3. RunnableBranch in LangChain With Examples
  4. Chain Using LangChain Expression Language With Examples
  5. RunablePassthrough in LangChain With Examples

You may also like-

  1. Structured Output In LangChain
  2. Messages in LangChain
  3. PreparedStatement Interface in Java-JDBC
  4. Pre-defined Functional Interfaces in Java
  5. Counting Sort Program in Java
  6. Python String join() Method
  7. Signal in Angular With Examples
  8. Circular Dependency in Spring Framework

No comments:

Post a Comment