Skip to main content

Lightweight local vector database with persistence to disk, supporting multiple similarity metrics and easy-to-use API.

Project description

microvector

Lightweight local vector database with persistence to disk, supporting multiple similarity metrics and an easy-to-use API.

A refactor and repackaging of HyperDB optimized for CPU-only environments with improved type safety and developer experience.

Features

  • 🚀 Simple API: Clean, intuitive interface with just two main methods: save() and search()
  • 💾 Persistent Storage: Automatically caches vector stores to .pickle.gz files
  • 🔍 Multiple Similarity Metrics: Choose from cosine, dot product, Euclidean, or Derrida distance
  • 🎯 Type Safe: Full type annotations with strict pyright compliance
  • CPU Optimized: Designed for CPU-only environments (no CUDA required)
  • 🔄 Flexible Caching: Use persistent stores or create temporary in-memory collections
  • 📦 Easy Installation: One-command setup with automatic PyTorch CPU configuration

Installation

pip install microvector

Or for development:

git clone https://github.com/loganpowell/microvector.git
cd microvector
uv sync

Quick Start

from microvector import Client

# Initialize the client
client = Client()

# Save a collection with automatic persistence
client.save(
    partition="my_documents",
    collection=[
        {"text": "Python is a popular programming language", "category": "tech"},
        {"text": "Machine learning models learn from data", "category": "ai"},
        {"text": "The quick brown fox jumps over the lazy dog", "category": "example"},
    ]
)

# Search the persisted collection
results = client.search(
    term="artificial intelligence and ML",
    partition="my_documents",
    key="text",
    top_k=5
)

for result in results:
    print(f"Score: {result['similarity_score']:.4f} - {result['text']}")

API Reference

Client

The main interface for all vector operations.

Client(
    cache_models: str = "./.cached_models",
    cache_vectors: str = "./.vector_cache",
    embedding_model: str = "avsolatorio/GIST-small-Embedding-v0"
)

Parameters:

  • cache_models: Directory for caching downloaded embedding models
  • cache_vectors: Directory for persisting vector stores
  • embedding_model: HuggingFace model name for generating embeddings

save()

Save a collection to a persistent vector store.

client.save(
    partition: str,
    collection: list[dict[str, Any]],
    key: str = "text",
    algo: str = "cosine"
) -> dict[str, Any]

Parameters:

  • partition: Unique identifier for this vector store
  • collection: List of documents (dictionaries) to vectorize
  • key: Field name to use for embedding (default: "text")
  • algo: Similarity metric - "cosine", "dot", "euclidean", or "derrida"

Returns:

{
    "status": "success",
    "partition": "my_documents",
    "documents_saved": 42,
    "key": "text",
    "algorithm": "cosine",
    "append": False,
    "embedding_model": "avsolatorio/GIST-small-Embedding-v0"
}

Example:

result = client.save(
    partition="products",
    collection=[
        {"description": "Wireless headphones", "price": 99.99},
        {"description": "Smart watch", "price": 299.99},
    ],
    key="description",
    algo="cosine"
)

search()

Search a vector store with semantic similarity.

client.search(
    term: str,
    partition: str,
    key: str = "text",
    top_k: int = 5,
    collection: Optional[list[dict[str, Any]]] = None,
    cache: bool = True,
    algo: str = "cosine",
    append: bool = False
) -> list[dict[str, Any]]

Parameters:

  • term: Search query string
  • partition: Name of the vector store to query
  • key: property within each item in the collection to search against (vectorized field)
  • top_k: Maximum number of results to return
  • collection: Optional temporary collection (for non-persistent search)
  • cache: If True, persist the collection; if False, keep in-memory only
  • algo: Similarity metric to use
  • append: If True, append to existing store; if False (default), replace existing store

Returns: List of documents with similarity scores

[
    {
        "text": "Machine learning is awesome",
        "category": "ai",
        "similarity_score": 0.923
    },
    ...
]

Example - Search existing store:

results = client.search(
    term="laptop computers",
    partition="products",
    key="description",
    top_k=3
)

Example - Temporary search (no persistence):

results = client.search(
    term="budget phones",
    partition="temp_search",
    key="description",
    top_k=5,
    collection=[
        {"description": "iPhone 15 Pro", "price": 999},
        {"description": "Samsung Galaxy S24", "price": 899},
    ],
    cache=False  # Don't save to disk
)

Similarity Algorithms

Algorithm Best For Range
cosine General text similarity (default) 0-1 (higher is more similar)
dot When magnitude matters Unbounded
euclidean Spatial distance 0-∞ (lower is more similar)
derrida Experimental alternative distance 0-∞ (lower is more similar)

Advanced Usage

Custom Embedding Models

Use any HuggingFace sentence-transformer model:

client = Client(
    embedding_model="intfloat/e5-small-v2"
)

Nested Key Paths

Access nested fields using dot notation:

collection = [
    {
        "product": {
            "name": "Laptop",
            "specs": {"cpu": "Intel i7"}
        }
    }
]

client.save(
    partition="products",
    collection=collection,
    key="product.name"
)

Working with Multiple Partitions

Organize different datasets in separate partitions:

# Save different content types
client.save("news_articles", news_data, key="content")
client.save("product_reviews", review_data, key="review_text")
client.save("support_tickets", tickets, key="description")

# Search each independently
news_results = client.search("economy", "news_articles", key="content")
review_results = client.search("quality", "product_reviews", key="review_text")

Incremental Updates with Append

Add new documents to existing vector stores without replacing them:

# Create initial store
client.save(
    partition="knowledge_base",
    key="text",
    collection=[
        {"text": "Python is a programming language"},
        {"text": "JavaScript runs in browsers"},
    ]
)

# Append more documents later
client.save(
    partition="knowledge_base",
    key="text",
    collection=[
        {"text": "TypeScript adds types to JavaScript"},
        {"text": "Rust is memory-safe"},
    ],
    append=True  # Adds to existing store instead of replacing
)

# Now the store contains all 4 documents

Temporary Append

Test new documents against existing corpus without persisting changes:

# Create persistent store
client.save(
    partition="products",
    key="text",
    collection=[
        {"text": "laptop computer", "price": 999},
        {"text": "wireless mouse", "price": 29},
    ]
)

# Temporarily add documents for a single search
results = client.search(
    term="computer accessories",
    partition="products",
    key="text",
    collection=[
        {"text": "USB-C hub", "price": 49},
        {"text": "laptop stand", "price": 39},
    ],
    cache=False,  # Don't persist
    append=True,  # But load existing cache and append temporarily
    top_k=4
)
# Returns 4 results (2 original + 2 temporary)

# Next search only finds the 2 original products
results = client.search(
    term="computer",
    partition="products",
    key="text",
    top_k=4
)
# Returns 2 results (temporary documents weren't persisted)

Development Setup

This project uses uv for dependency management and automatically configures CPU-only PyTorch.

Quick Start

  1. Install dependencies:

    uv sync
    
  2. Verify setup:

    uv run python setup_dev.py
    
  3. Run tests:

    uv run pytest
    
  4. Type checking:

    uv run pyright
    

What Gets Installed

  • PyTorch (CPU-only): Automatically from PyTorch CPU index
  • Transformers: HuggingFace transformers library
  • Sentence Transformers: For embedding generation
  • NumPy: Numerical computing

No special flags or manual PyTorch installation needed - just uv sync and go!

Performance Tips

  1. Reuse Client instances - Model loading is expensive
  2. Use persistent caching - Vector computation is cached automatically
  3. Batch your saves - Save collections together when possible
  4. Choose the right algorithm - Cosine is fastest for most use cases
  5. Adjust top_k - Lower values are faster

Architecture

microvector/
├── main.py          # Client API
├── store.py         # Vector storage and similarity search
├── cache.py         # Persistence layer
├── embed.py         # Embedding generation
├── algos.py         # Similarity algorithms
└── utils.py         # Helper functions

License

MIT License - see LICENSE file for details.

Credits

Based on HyperDB by John Dagdelen. Refactored and maintained by Logan Powell.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

microvector-0.2.17.tar.gz (160.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

microvector-0.2.17-py3-none-any.whl (25.8 kB view details)

Uploaded Python 3

File details

Details for the file microvector-0.2.17.tar.gz.

File metadata

  • Download URL: microvector-0.2.17.tar.gz
  • Upload date:
  • Size: 160.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for microvector-0.2.17.tar.gz
Algorithm Hash digest
SHA256 1993a2c4d5016b27e8012db16ad0c8bfb5917e324a4dfe20a9b8d77e08f59dc4
MD5 e903b2e412a681f1767e98895893cb4b
BLAKE2b-256 36ba717eeffc896451603a463d426ab9c400c34751f6e8846bf7bb7420ed518e

See more details on using hashes here.

Provenance

The following attestation bundles were made for microvector-0.2.17.tar.gz:

Publisher: publish.yml on loganpowell/microvector

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file microvector-0.2.17-py3-none-any.whl.

File metadata

  • Download URL: microvector-0.2.17-py3-none-any.whl
  • Upload date:
  • Size: 25.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for microvector-0.2.17-py3-none-any.whl
Algorithm Hash digest
SHA256 5a260090240d2028cb2bbf5b660be43c2713ae52640cebdc698f5fec70028792
MD5 1daa1f09da69400e77bbf11c7ae41795
BLAKE2b-256 a3c2a06a75fd683b51158f8a6208146afb38ff0667d36d011b228fb94885d718

See more details on using hashes here.

Provenance

The following attestation bundles were made for microvector-0.2.17-py3-none-any.whl:

Publisher: publish.yml on loganpowell/microvector

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page