Skip to main content

Overview

The VectorStore class manages your vector database using Milvus, a high-performance vector database designed for similarity search. It handles:
  • Storage: Efficiently store embeddings with metadata
  • Search: Fast similarity search using vector indexes
  • Hybrid Search: Combine semantic and keyword (BM25) search
  • Management: Create, update, and delete collections

Basic Usage

import os
from mini.store import VectorStore

# Initialize vector store
vector_store = VectorStore(
    uri=os.getenv("MILVUS_URI"),
    token=os.getenv("MILVUS_TOKEN"),
    collection_name="my_documents",
    dimension=1536  # Must match embedding dimension
)

# Insert embeddings
ids = vector_store.insert(
    embeddings=embeddings,
    texts=["First chunk", "Second chunk"],
    metadata=[
        {"source": "doc1.pdf", "page": 1},
        {"source": "doc1.pdf", "page": 2}
    ]
)

# Search for similar vectors
query_embedding = embedding_model.embed_query("What is this about?")
results = vector_store.search(
    query_embedding=query_embedding,
    top_k=5
)

# Get collection statistics
count = vector_store.count()
print(f"Total documents: {count}")

Configuration

Basic Configuration

vector_store = VectorStore(
    uri="https://your-milvus-instance.com",
    token="your-token",
    collection_name="documents",
    dimension=1536
)

Advanced Configuration

from mini.store import MilvusConfig, VectorStore

config = MilvusConfig(
    uri="https://your-instance.com",
    token="your-token",
    collection_name="documents",
    dimension=1536,
    metric_type="IP",        # IP (cosine), L2, or COSINE
    index_type="IVF_FLAT",   # IVF_FLAT, IVF_SQ8, HNSW
    nlist=128                # Number of cluster units
)

vector_store = VectorStore(config=config)

Similarity Metrics

Choose the right metric for your use case:
MetricDescriptionBest For
IP (Inner Product)Cosine similarity (default)Most use cases, normalized embeddings
L2Euclidean distanceAbsolute distance matters
COSINECosine similarity (explicit)When using non-normalized vectors
# Using cosine similarity (recommended)
vector_store = VectorStore(
    uri=os.getenv("MILVUS_URI"),
    token=os.getenv("MILVUS_TOKEN"),
    collection_name="docs",
    dimension=1536,
    metric_type="IP"  # Inner Product = Cosine for normalized vectors
)

Index Types

Different index types offer tradeoffs between speed and accuracy:
Highest performance for large datasets
  • Fastest search speed
  • High accuracy
  • Higher memory usage
vector_store = VectorStore(
    uri=os.getenv("MILVUS_URI"),
    token=os.getenv("MILVUS_TOKEN"),
    collection_name="docs",
    dimension=1536,
    index_type="HNSW"
)
Memory-optimized
  • Lower memory footprint
  • Good performance
  • Slightly lower accuracy
vector_store = VectorStore(
    uri=os.getenv("MILVUS_URI"),
    token=os.getenv("MILVUS_TOKEN"),
    collection_name="docs",
    dimension=1536,
    index_type="IVF_SQ8"
)

Operations

Insert Embeddings

# Insert with metadata
ids = vector_store.insert(
    embeddings=[[0.1, 0.2, ...], [0.3, 0.4, ...]],
    texts=["First document", "Second document"],
    metadata=[
        {"source": "doc1.pdf", "page": 1, "category": "research"},
        {"source": "doc2.pdf", "page": 1, "category": "tutorial"}
    ]
)

print(f"Inserted {len(ids)} vectors")
# Basic search
results = vector_store.search(
    query_embedding=query_embedding,
    top_k=5
)

for result in results:
    print(f"Score: {result['score']}")
    print(f"Text: {result['text']}")
    print(f"Metadata: {result['metadata']}")

Search with Filters

# Filter by metadata
results = vector_store.search(
    query_embedding=query_embedding,
    top_k=5,
    filter_expr='metadata["category"] == "research"'
)

# Complex filters
results = vector_store.search(
    query_embedding=query_embedding,
    top_k=5,
    filter_expr='metadata["year"] >= 2023 and metadata["category"] == "research"'
)
Combine semantic (vector) and keyword (BM25) search:
# Enable hybrid search when creating vector store
vector_store = VectorStore(
    uri=os.getenv("MILVUS_URI"),
    token=os.getenv("MILVUS_TOKEN"),
    collection_name="docs",
    dimension=1536,
    enable_hybrid_search=True  # Enable BM25 + semantic
)

# Search with hybrid mode
results = vector_store.hybrid_search(
    query="budget allocation for railways",
    query_embedding=query_embedding,
    top_k=10
)

Learn more about Hybrid Search

Discover how to combine semantic and keyword search for better results

Delete Vectors

# Delete by filter expression
num_deleted = vector_store.delete(
    expr='metadata["year"] < 2020'
)
print(f"Deleted {num_deleted} vectors")

Get Collection Info

# Get total count
count = vector_store.count()
print(f"Total vectors: {count}")

# Get collection statistics
stats = vector_store.get_collection_stats()
print(stats)

Drop Collection

This permanently deletes all data in the collection. Use with caution!
# Drop entire collection
vector_store.drop_collection()

Integration with AgenticRAG

When using AgenticRAG, vector storage is handled automatically:
from mini import AgenticRAG, EmbeddingModel, VectorStore

# Setup vector store
vector_store = VectorStore(
    uri=os.getenv("MILVUS_URI"),
    token=os.getenv("MILVUS_TOKEN"),
    collection_name="docs",
    dimension=1536
)

# Use with RAG
rag = AgenticRAG(
    vector_store=vector_store,
    embedding_model=embedding_model
)

# Storage is handled automatically
rag.index_document("document.pdf")
response = rag.query("What is this about?")

Best Practices

Use descriptive, consistent names:
  • company_docs_v1 - Good
  • my_collection - Less descriptive
  • Use versioning for schema changes
vector_store = VectorStore(
    uri=os.getenv("MILVUS_URI"),
    token=os.getenv("MILVUS_TOKEN"),
    collection_name="company_docs_v1",
    dimension=1536
)
Store useful metadata for filtering:
metadata = {
    "source": "document.pdf",      # Document source
    "page": 5,                      # Page number
    "category": "research",         # Category
    "author": "John Doe",          # Author
    "date": "2024-01-15",          # Date
    "tags": ["ai", "ml", "rag"]    # Tags
}
Insert in batches for better performance:
# Good: Batch insert
vector_store.insert(
    embeddings=all_embeddings,
    texts=all_texts,
    metadata=all_metadata
)

# Bad: Individual inserts
# for emb, text, meta in zip(embeddings, texts, metadata):
#     vector_store.insert([emb], [text], [meta])
Disconnect when done:
try:
    # Use vector store
    results = vector_store.search(...)
finally:
    # Clean up connection
    vector_store.disconnect()

Advanced Usage

Custom Output Fields

# Specify which fields to return
results = vector_store.search(
    query_embedding=query_embedding,
    top_k=5,
    output_fields=["text", "metadata"]
)

Multiple Collections

# Use different collections for different purposes
docs_store = VectorStore(
    uri=os.getenv("MILVUS_URI"),
    token=os.getenv("MILVUS_TOKEN"),
    collection_name="documents",
    dimension=1536
)

code_store = VectorStore(
    uri=os.getenv("MILVUS_URI"),
    token=os.getenv("MILVUS_TOKEN"),
    collection_name="code_snippets",
    dimension=1536
)

Upsert Operations

# Update or insert
# First delete existing
vector_store.delete(expr='metadata["doc_id"] == "doc123"')

# Then insert new version
vector_store.insert(
    embeddings=new_embeddings,
    texts=new_texts,
    metadata=[{"doc_id": "doc123", ...}]
)

Performance Tuning

Index Selection

Choose index type based on dataset size and requirements

Batch Size

Insert 100-1000 vectors per batch for optimal performance

Memory Management

Monitor memory usage, especially with HNSW index

Query Optimization

Use filters to reduce search space

Troubleshooting

Solution: Check Milvus connection:
# Verify connection
try:
    count = vector_store.count()
    print(f"Connected! Vector count: {count}")
except Exception as e:
    print(f"Connection error: {e}")
Solution: Ensure vector store dimension matches embeddings:
# Check embedding dimension
test_embedding = embedding_model.embed_query("test")
print(f"Embedding dim: {len(test_embedding)}")

# Create matching vector store
vector_store = VectorStore(
    uri=os.getenv("MILVUS_URI"),
    token=os.getenv("MILVUS_TOKEN"),
    collection_name="docs",
    dimension=len(test_embedding)
)
Solution: Optimize index and search parameters:
# Use HNSW for faster search
vector_store = VectorStore(
    uri=os.getenv("MILVUS_URI"),
    token=os.getenv("MILVUS_TOKEN"),
    collection_name="docs",
    dimension=1536,
    index_type="HNSW"
)
Solution: Use a different name or drop existing:
# Use versioned names
vector_store = VectorStore(
    uri=os.getenv("MILVUS_URI"),
    token=os.getenv("MILVUS_TOKEN"),
    collection_name="docs_v2",  # New version
    dimension=1536
)

Milvus Deployment Options

Next Steps