Fun with Learning Technology
LearnCoursesQuestionsTracksToolsNewsExplorePractice
Fun with Learning Technology

A new problem, explained clearly, every day.

Subscribe
Learn
  • Lessons
  • Topics
  • News
  • Tools
  • Courses
  • Career tracks
  • Everything
Site
  • About
  • Contact
  • Support
  • Privacy
  • Terms
Get the daily one

One email per new problem. No spam.

Request a tutorial

Requests shape what gets made next.

© 2026 Fun with Learning TechnologyRSS
Home›Courses›Generative AI›ChromaDB — Setup and Usage

Vector Databases

ChromaDB — Setup and Usage

ChromaDB is an open-source, embedding-native vector database designed to simplify the storage and retrieval of high-dimensional semantic data. It matters because it allows developers to easily augment large language models with external knowledge through efficient similarity search without managing complex infrastructure. You should reach for it when building Retrieval-Augmented Generation systems where low-latency semantic search over unstructured text is a primary requirement.

Installation and Client Initialization

To begin using ChromaDB, you must understand that it operates as a client-server architecture that abstracts away the complexities of local data persistence. When you initialize a client, you are essentially establishing a bridge to a storage engine that handles the indexing of vectors. The local mode creates a directory on your machine to save data, ensuring that your work persists across sessions without requiring a dedicated server setup. This is the simplest entry point for developers because it manages the underlying file system interactions autonomously. Understanding this initialization is crucial because it sets the scope for where your data will reside and how it will be retrieved during your application's lifecycle. By configuring a persistent path, you ensure that your vector space remains intact, which is fundamental for maintaining the reliability of your retrieval pipelines as you add more content to your system over time.

import chromadb

# Initialize a persistent client that saves data to the './data' directory
# This ensures that your vector collections survive program restarts
client = chromadb.PersistentClient(path='./data')

print("Client initialized and ready for collection operations.")

Managing Collections

A collection in ChromaDB acts similarly to a table in a traditional relational database, serving as the container for your documents and their associated embeddings. Creating a collection requires you to define a name, which serves as a unique identifier for retrieving that specific set of data. Why does this design exist? Because it allows you to logically segment your knowledge base into distinct domains, such as separating product manuals from customer support logs. When you create a collection, ChromaDB automatically sets up the necessary index structures to support similarity search. This abstraction is powerful because it allows you to switch between different data segments programmatically. You should think of collections as independent memory spaces where the database maintains mappings between your original text documents and the mathematical vectors that represent their semantic meaning, allowing for high-speed comparisons later during retrieval operations.

import chromadb

client = chromadb.PersistentClient(path='./data')

# Create a collection to store specific knowledge documents
# ChromaDB uses a default embedding function if none is specified
collection = client.get_or_create_collection(name="technical_docs")

print(f"Collection '{collection.name}' is ready to store data.")

Adding Data and Embeddings

When you add data to a collection, you provide both the document text and a unique identifier for that record. The database takes these inputs and processes them through an embedding function to generate a numerical vector representation. This vector represents the 'meaning' of the text within a high-dimensional space. The key takeaway here is that the database stores both the raw text (the metadata) and the vector. Storing them together is efficient because it enables the system to perform a mathematical operation called 'cosine similarity' to find vectors that are physically close to each other, which logically corresponds to texts that are semantically similar. By explicitly managing IDs, you maintain the ability to update or delete specific chunks of knowledge, which is essential for keeping your retrieval system accurate as the underlying source data evolves or gets corrected over time in your environment.

collection = client.get_or_create_collection(name="technical_docs")

# Add documents with unique identifiers
# These are converted to vectors internally by the database engine
collection.add(
    documents=["Python is a high-level programming language.", "The database provides fast search."],
    ids=["id1", "id2"]
)

print("Data ingested and indexed successfully.")

Performing Semantic Queries

The true utility of a vector database is revealed during the retrieval phase, where you provide a natural language query that is converted into a vector and then compared against all stored vectors in your collection. Unlike keyword matching, which looks for literal character sequences, a semantic query looks for mathematical proximity. This allows the system to return results that match the intent or context of your query, even if the exact words are different. When you perform a query, you specify the number of 'top-k' results you want to retrieve. The database calculates the distance between your query vector and the stored vectors, returning the closest matches. This mechanism is the core of any Retrieval-Augmented Generation pipeline. By understanding this, you can reason about how to tune your results by adjusting the number of documents returned to match the context window constraints of your language model.

results = collection.query(
    query_texts=["How can I search data quickly?"],
    n_results=1 # Return the single most semantically relevant document
)

# Inspect the query results to see the matched text
print(f"Found: {results['documents'][0][0]}")

Updating and Deleting Records

Maintenance of a vector database involves more than just adding data; you must also manage the lifecycle of your records through updates and deletions. Because each record is associated with a unique ID, you can perform targeted deletions if a specific document becomes obsolete or incorrect. Updating is essentially a deletion followed by an addition under the same identifier. This is critical for systems that require high data hygiene, such as those relying on frequently updated technical documentation. If your search results are consistently pointing to outdated information, your ability to perform targeted updates ensures that the database reflects the current source of truth. By systematically managing your IDs, you ensure that your embedding space remains uncluttered, directly improving the precision and relevance of the results returned by your future queries, which is vital for building reliable, production-grade applications that users can trust.

# Remove a specific document by its identifier
collection.delete(ids=["id1"])

# The document is now removed from the collection and search index
print("Document 'id1' has been removed from the vector database.")

Key points

  • ChromaDB acts as a persistent layer that maps raw text to semantic vector space.
  • Collections serve as the primary organizational unit for grouping distinct documents.
  • Data is ingested by transforming text into high-dimensional vectors that represent meaning.
  • The database manages the association between unique identifiers and their corresponding vectors.
  • Similarity search relies on mathematical proximity rather than exact keyword matching.
  • Developers can control the quality of information retrieval by adjusting the number of returned results.
  • Targeted updates and deletions are enabled through the use of unique document identifiers.
  • Maintaining a clean database ensures that search results remain relevant to the intended context.

Common mistakes

  • Mistake: Forgetting to handle persistent storage. Why it's wrong: By default, ChromaDB uses an ephemeral (in-memory) client, meaning all data is lost when the script finishes. Fix: Provide a persistent directory path to the PersistentClient when initializing the database.
  • Mistake: Overwriting collections instead of updating them. Why it's wrong: Calling create_collection repeatedly without checking for existence raises an error. Fix: Use get_or_create_collection to safely retrieve or initialize your storage area.
  • Mistake: Neglecting to define an embedding function. Why it's wrong: Without an explicit embedding function, the database cannot translate raw text into vector representations. Fix: Pass a pre-configured embedding function (such as an open-source model) to the collection during setup.
  • Mistake: Assuming query results are sorted by relevance automatically. Why it's wrong: While queries return distances, users often ignore the 'distance' metric, misinterpreting the order of results. Fix: Always inspect the returned 'distances' list, where lower values indicate higher similarity.
  • Mistake: Inserting duplicate IDs into a collection. Why it's wrong: ChromaDB enforces unique IDs for documents; adding a duplicate ID will cause an insertion failure. Fix: Implement a hashing strategy or UUID generation for document IDs before ingestion.

Interview questions

What is ChromaDB and why is it essential for building Generative AI applications?

ChromaDB is an open-source, AI-native vector database designed to handle the storage and retrieval of high-dimensional embeddings. In Generative AI, large language models have a finite context window and no inherent memory of specific private data. ChromaDB solves this by allowing developers to store document chunks as embeddings and perform semantic similarity searches, which are then passed as context to a model to generate accurate, ground-truth responses.

How do you perform the initial setup and basic collection creation in ChromaDB?

To set up ChromaDB, you typically install the library and initialize a client using persistent storage. For example, 'client = chromadb.PersistentClient(path='./my_db')'. Once the client is ready, you create a collection using 'collection = client.create_collection(name='knowledge_base')'. This collection acts as the container for your embeddings. It is essential because it allows you to organize your vectorized data logically, ensuring you can perform efficient CRUD operations for your specific domain knowledge.

Explain the process of adding documents to a collection and how ChromaDB handles the embedding generation.

When adding documents, you use the 'collection.add()' method, passing in unique IDs, the raw document strings, and optionally their associated embeddings. If you do not provide embeddings, ChromaDB can automatically utilize a built-in default embedding function to convert text into vectors. This is a critical convenience, as it abstracts the complex math of mapping tokens to high-dimensional space, allowing developers to focus on the semantic quality of their retrieved information.

How does semantic search work within ChromaDB, and what is the role of the 'n_results' parameter?

Semantic search in ChromaDB operates by converting a user's query into a vector and calculating the distance (usually cosine distance) between that query vector and the stored document vectors. The 'n_results' parameter defines the number of top-matching chunks to return. This is vital for Generative AI because it controls the amount of information injected into the prompt; too few results might miss context, while too many might exceed the model's token limit.

Compare the approach of using an in-memory ChromaDB instance versus a persistent disk-based client in production environments.

Using an in-memory client is ideal for rapid prototyping, unit testing, or ephemeral tasks where data persistence is unnecessary. However, for any robust production Generative AI application, a persistent disk-based client is mandatory. Persistence ensures that your vector embeddings remain intact after the process terminates. Relying on an in-memory database would force you to re-compute all embeddings upon every restart, which is computationally expensive and introduces significant latency to your system startup.

How would you implement a workflow to update existing document embeddings without duplicating entries in ChromaDB?

To prevent duplicates, you should leverage the unique identifier system in ChromaDB. Instead of repeatedly adding content, you can utilize the 'collection.upsert()' method. When you pass an ID that already exists, the database automatically updates the associated vector and metadata instead of creating a new entry. This is a best practice in Generative AI pipelines because it ensures that when your knowledge base grows or documents are revised, the context retrieved for the model remains accurate and current.

All Generative AI interview questions →

Check yourself

1. Which of the following best describes the purpose of a collection in ChromaDB?

  • A.A database that stores only raw text strings without vectorization.
  • B.A logical grouping of documents and their corresponding vector embeddings.
  • C.A system configuration file that handles environment authentication.
  • D.A temporary buffer used only for streaming high-volume API requests.
Show answer

B. A logical grouping of documents and their corresponding vector embeddings.
Collections are the primary mechanism for organizing data. Option 1 is wrong because it handles vectors; option 3 is wrong because it's data-focused; option 4 is wrong because collections are persistent, not just buffers.

2. Why is the choice of distance metric important when querying a collection?

  • A.It determines the hardware requirements for the CPU.
  • B.It defines the mathematical threshold for what qualifies as a match.
  • C.It alters how text is tokenized before being sent to the LLM.
  • D.It controls the physical location where the files are written on the disk.
Show answer

B. It defines the mathematical threshold for what qualifies as a match.
Distance metrics define similarity. Option 1 is incorrect as hardware is independent; option 3 is wrong as tokenization happens in the embedding step; option 4 is wrong as storage location is defined by the client path.

3. What is the primary benefit of using a PersistentClient compared to an ephemeral client?

  • A.It provides faster encryption of sensitive data.
  • B.It allows multiple processes to access the database concurrently.
  • C.It ensures that embedded vector data survives across application restarts.
  • D.It automatically reduces the dimension size of your vectors.
Show answer

C. It ensures that embedded vector data survives across application restarts.
Persistence ensures data stays on disk. Option 1 is wrong as it's not an encryption tool; option 2 is not the definition of persistence; option 4 is wrong as dimension size is fixed by the embedding model.

4. When performing a query, what does a distance value of '0' suggest?

  • A.The document is completely irrelevant to the query.
  • B.The query was unable to find any matches in the collection.
  • C.The document vector is identical to the query vector.
  • D.The embedding model encountered an error during processing.
Show answer

C. The document vector is identical to the query vector.
In vector search (specifically cosine/l2), 0 distance implies identity. Option 1 describes a high distance; option 2 suggests failure; option 4 is unrelated to the distance metric calculation.

5. How does ChromaDB handle the relationship between raw text and vector embeddings during ingestion?

  • A.It ignores the raw text and stores only the resulting vector.
  • B.It automatically maps the original document to the generated vector embedding.
  • C.It requires a separate SQL database to link text to vectors.
  • D.It asks the user to manually input the vectors associated with every text block.
Show answer

B. It automatically maps the original document to the generated vector embedding.
ChromaDB acts as a document store that keeps the metadata (text) linked to the vector. Option 1 is false as the text is useful for retrieval; option 3 is unnecessary complexity; option 4 is false as the library handles embedding generation.

Take the full Generative AI quiz →

← PreviousIntroduction to Vector DatabasesNext →Pinecone — Setup and Usage

Generative AI

41 lessons, free to read.

All lessons →

Track your progress

Sign in to mark lessons done, score quizzes and keep notes.

Open in the app