LangChain Vector Stores

LangChain vector stores save documents together with their embeddings and let you search for the most similar ones to a query. We use Chroma, an open-source vector database that runs inside your Python process, through the langchain-chroma package.

Creating a Chroma Vector Store

from langchain_chroma import Chroma
from langchain_ollama import OllamaEmbeddings
from langchain_core.documents import Document

emb = OllamaEmbeddings(model="nomic-embed-text")
store = Chroma(
    collection_name="faq",
    embedding_function=emb,
    persist_directory="./chroma_db",
)
docs = [
    Document("Shipping takes 3-5 business days.", metadata={"topic": "shipping"}),
    Document("Returns are free within 30 days.", metadata={"topic": "returns"}),
    Document("We ship to Pakistan, UAE and the UK.", metadata={"topic": "shipping"}),
]
ids = store.add_documents(docs)
print(len(ids), "documents added")
3 documents added

add_documents embeds each document with the embedding function and stores text, vector and metadata. Because persist_directory is set, the data survives restarts; omit it for an in-memory store.

Similarity Search

results = store.similarity_search("How long does delivery take?", k=2)
for d in results:
    print(d.page_content, d.metadata)

for d, score in store.similarity_search_with_score("Can I send it back?", k=1):
    print(round(score, 3), d.page_content)
Sample output:
Shipping takes 3-5 business days. {'topic': 'shipping'}
We ship to Pakistan, UAE and the UK. {'topic': 'shipping'}
0.412 Returns are free within 30 days.

Chroma returns a distance score by default, so lower means more similar. k controls how many results come back.

Filtering by Metadata

hits = store.similarity_search("countries", k=3, filter={"topic": "shipping"})
print([h.page_content for h in hits])
Sample output:
['We ship to Pakistan, UAE and the UK.', 'Shipping takes 3-5 business days.']

Updating and Deleting

  • Pass ids=[...] to add_documents to control IDs and make re-indexing idempotent.
  • store.delete(ids=[...]) removes documents.
  • Chroma.from_documents(docs, emb) creates and fills a store in one call.
  • Reopen a persisted store by creating Chroma with the same collection_name and persist_directory.

Other Vector Stores

The same interface works for many databases: PGVector (langchain-postgres) for PostgreSQL, QdrantVectorStore (langchain-qdrant), FAISS (in langchain-community) and InMemoryVectorStore in langchain-core for quick tests. Switching usually only changes the constructor.

Frequently asked questions

Which vector store should I use with LangChain?

Chroma or InMemoryVectorStore for learning and prototypes; pgvector if you already use PostgreSQL; Qdrant or similar dedicated databases for large-scale production.

Is a lower Chroma score better?

Yes, similarity_search_with_score in Chroma returns a distance, so smaller is more similar. Use similarity_search_with_relevance_scores for a 0 to 1 score where higher is better.

How do I avoid duplicate documents in Chroma?

Generate deterministic IDs (for example a hash of source and chunk index) and pass them to add_documents so re-adding overwrites instead of duplicating.