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:
Metric Description Best For IP (Inner Product)Cosine similarity (default) Most use cases, normalized embeddings L2 Euclidean distance Absolute distance matters COSINE Cosine 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:
Best balance for most use cases
Good search performance
High accuracy
Moderate memory usage
vector_store = VectorStore(
uri = os.getenv( "MILVUS_URI" ),
token = os.getenv( "MILVUS_TOKEN" ),
collection_name = "docs" ,
dimension = 1536 ,
index_type = "IVF_FLAT" ,
nlist = 128 # Number of clusters
)
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" )
Semantic Search
# 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"'
)
Hybrid Search
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
)
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" , ... }]
)
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)
)
Collection already exists
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