AI Model Wiki

    Skip to main content
    40 min
    Lesson 3 of 5

    Querying & Filtering

    From the course ChromaDB: Local Vector Database

    Querying ChromaDB

    Semantic Search

    results = collection.query(
        query_texts=["What causes rain?"],
        n_results=5,
        include=["documents", "metadatas", "distances"]
    )
    

    Metadata Filtering

    results = collection.query(
        query_texts=["machine learning"],
        n_results=10,
        where={"topic": "technology"},
        where_document={"$contains": "neural"}
    )
    

    Filter Operators

    # Comparison
    where={"year": {"$gt": 2023}}
    where={"price": {"$lte": 50}}
    
    # Logical
    where={"$and": [
        {"category": "science"},
        {"year": {"$gte": 2023}}
    ]}
    
    where={"$or": [
        {"status": "published"},
        {"status": "featured"}
    ]}
    

    Updating & Deleting

    # Update documents
    collection.update(
        ids=["doc1"],
        documents=["Updated content"],
        metadatas=[{"topic": "updated"}]
    )
    
    # Delete by ID
    collection.delete(ids=["doc1", "doc2"])
    
    # Delete by filter
    collection.delete(where={"status": "archived"})
    

    Common Pitfall: Forgetting to Include Metadata at Upsert Time

    You cannot add metadata to a document after it has been inserted without calling update(). If you add 10,000 documents and forget the metadatas parameter, you'll need to update every record individually — an expensive operation. Always plan your metadata schema before bulk ingestion and add it upfront.

    Best Practice: Use upsert Instead of add

    For pipelines that re-index documents regularly, prefer collection.upsert() over collection.add(). The add method raises an error if an ID already exists, while upsert creates or updates as needed. This makes your ingestion pipeline idempotent:

    # Idempotent ingestion — safe to re-run
    collection.upsert(
        documents=["Updated content here"],
        ids=["doc1"],
        metadatas=[{"version": 2, "updated_at": "2025-01-01"}],
    )
    

    Advanced Filter Example: Date Range Query

    A common real-world pattern is filtering documents by recency while also doing semantic search:

    import time
    
    one_week_ago = int(time.time()) - 7 * 86400
    
    results = collection.query(
        query_texts=["machine learning breakthroughs"],
        n_results=5,
        where={
            "$and": [
                {"published_ts": {"$gte": one_week_ago}},
                {"source": {"$in": ["arxiv", "blog"]}},
            ]
        },
    )
    

    Store Unix timestamps as integers in metadata — ChromaDB's filter operators work on numeric types but not ISO date strings.

    Key Takeaways

    • •Query with text (auto-embedded) or raw vectors
    • •Combine semantic search with metadata and document content filters
    • •Use logical operators ($and, $or) for complex filter conditions
    • •Update and delete operations support both ID and filter-based targeting
    0 of 5 lessons marked complete

    Progress is kept in this browser only.