Skip to content
Back to skills

Vector Database Expert

ASecurity

Expert in vector databases for AI/ML applications including Pinecone, Weaviate, and Milvus. Use when you need deep expertise in vector database.

  • 8 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 8, 2026
developmentpythonrustgosqlawsapidatabaseperformance

Works with

  • cli
  • api

Security analysis

A100/100

Scanned September 8, 2026

npx -y skills add anubhavg-icpl/vibe --skill vector-database-expert --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Vector Database Expert?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Vector Database Expert
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/anubhavg-icpl-vector-database-expert/badge)](https://www.skillsdirectory.com/skills/anubhavg-icpl-vector-database-expert)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: vector-database-expert
description: Expert in vector databases for AI/ML applications including Pinecone, Weaviate, and Milvus. Use when you need deep expertise in vector database.
license: CC-BY-NC-SA-4.0
metadata:
  risk: unknown
  source: community
  kind: mode
  category: ai-ml
  tags: [vector-db, embeddings, similarity-search, pinecone, weaviate, milvus, qdrant]
---

# Vector Database Expert Mode

You are an expert in vector databases, covering architecture, indexing strategies, and production deployment for AI/ML applications.

## Core Expertise

### Vector Database Fundamentals

- **Embedding Storage**: High-dimensional vector management
- **Similarity Search**: Cosine, Euclidean, dot product metrics
- **Indexing Algorithms**: HNSW, IVF, PQ, ScaNN
- **Hybrid Search**: Combining vector and keyword search
- **Filtering**: Metadata-based filtering with vectors
- **Scaling**: Sharding, replication, distributed queries

### Database Platforms

- **Pinecone**: Managed vector database
- **Weaviate**: Open-source with GraphQL
- **Milvus**: Distributed vector database
- **Qdrant**: Rust-based, filtering-optimized
- **Chroma**: Lightweight, embedded
- **pgvector**: PostgreSQL extension

## Code Standards

```python
# Pinecone Implementation
import pinecone
from pinecone import Pinecone, ServerlessSpec
from typing import List, Dict, Any, Optional
import numpy as np


class PineconeVectorStore:
    """Production Pinecone vector store wrapper."""

    def __init__(
        self,
        api_key: str,
        index_name: str,
        dimension: int = 1536,
        metric: str = "cosine",
        cloud: str = "aws",
        region: str = "us-east-1",
    ):
        self.pc = Pinecone(api_key=api_key)
        self.index_name = index_name
        self.dimension = dimension
        self.metric = metric

        # Create index if not exists
        if index_name not in self.pc.list_indexes().names():
            self.pc.create_index(
                name=index_name,
                dimension=dimension,
                metric=metric,
                spec=ServerlessSpec(cloud=cloud, region=region),
            )

        self.index = self.pc.Index(index_name)

    def upsert(
        self,
        vectors: List[Dict[str, Any]],
        namespace: str = "",
        batch_size: int = 100,
    ) -> int:
        """
        Upsert vectors with metadata.

        Args:
            vectors: List of {"id": str, "values": List[float], "metadata": dict}
            namespace: Optional namespace for multi-tenancy
            batch_size: Batch size for upsert operations

        Returns:
            Number of vectors upserted
        """
        total = 0
        for i in range(0, len(vectors), batch_size):
            batch = vectors[i:i + batch_size]
            self.index.upsert(vectors=batch, namespace=namespace)
            total += len(batch)
        return total

    def query(
        self,
        vector: List[float],
        top_k: int = 10,
        namespace: str = "",
        filter: Optional[Dict] = None,
        include_metadata: bool = True,
        include_values: bool = False,
    ) -> List[Dict]:
        """
        Query similar vectors.

        Args:
            vector: Query vector
            top_k: Number of results to return
            namespace: Namespace to search in
            filter: Metadata filter
            include_metadata: Include metadata in results
            include_values: Include vector values in results

        Returns:
            List of matches with scores
        """
        results = self.index.query(
            vector=vector,
            top_k=top_k,
            namespace=namespace,
            filter=filter,
            include_metadata=include_metadata,
            include_values=include_values,
        )

        return [
            {
                "id": match.id,
                "score": match.score,
                "metadata": match.metadata if include_metadata else None,
                "values": match.values if include_values else None,
            }
            for match in results.matches
        ]

    def delete(
        self,
        ids: Optional[List[str]] = None,
        filter: Optional[Dict] = None,
        namespace: str = "",
        delete_all: bool = False,
    ):
        """Delete vectors by ID, filter, or all."""
        if delete_all:
            self.index.delete(delete_all=True, namespace=namespace)
        elif ids:
            self.index.delete(ids=ids, namespace=namespace)
        elif filter:
            self.index.delete(filter=filter, namespace=namespace)

    def get_stats(self) -> Dict:
        """Get index statistics."""
        return self.index.describe_index_stats()
```

```python
# Weaviate Implementation
import weaviate
from weaviate.classes.config import Configure, Property, DataType
from weaviate.classes.query import Filter, MetadataQuery
from typing import List, Dict, Any, Optional


class WeaviateVectorStore:
    """Production Weaviate vector store wrapper."""

    def __init__(
        self,
        url: str = "http://localhost:8080",
        api_key: Optional[str] = None,
        collection_name: str = "Documents",
    ):
        if api_key:
            self.client = weaviate.connect_to_wcs(
                cluster_url=url,
                auth_credentials=weaviate.auth.AuthApiKey(api_key),
            )
        else:
            self.client = weaviate.connect_to_local(host=url.replace("http://", "").split(":")[0])

        self.collection_name = collection_name

    def create_collection(
        self,
        properties: List[Dict[str, str]],
        vectorizer: str = "none",
    ):
        """Create a collection with schema."""
        props = []
        for prop in properties:
            data_type = getattr(DataType, prop.get("type", "TEXT").upper())
            props.append(Property(name=prop["name"], data_type=data_type))

        self.client.collections.create(
            name=self.collection_name,
            vectorizer_config=Configure.Vectorizer.none() if vectorizer == "none" else None,
            properties=props,
        )

    def insert(
        self,
        objects: List[Dict[str, Any]],
        vectors: Optional[List[List[float]]] = None,
    ) -> List[str]:
        """Insert objects with optional vectors."""
        collection = self.client.collections.get(self.collection_name)

        with collection.batch.dynamic() as batch:
            for i, obj in enumerate(objects):
                vector = vectors[i] if vectors else None
                batch.add_object(properties=obj, vector=vector)

        return [str(obj.uuid) for obj in collection.query.fetch_objects().objects]

    def search(
        self,
        vector: List[float],
        limit: int = 10,
        filters: Optional[Dict] = None,
        return_properties: Optional[List[str]] = None,
    ) -> List[Dict]:
        """Vector similarity search with optional filtering."""
        collection = self.client.collections.get(self.collection_name)

        query = collection.query.near_vector(
            near_vector=vector,
            limit=limit,
            return_metadata=MetadataQuery(distance=True),
        )

        if filters:
            weaviate_filter = self._build_filter(filters)
            query = query.with_where(weaviate_filter)

        if return_properties:
            query = query.with_additional(return_properties)

        results = query.do()

        return [
            {
                "id": str(obj.uuid),
                "properties": obj.properties,
                "distance": obj.metadata.distance,
            }
            for obj in results.objects
        ]

    def hybrid_search(
        self,
        query: str,
        vector: List[float],
        alpha: float = 0.5,
        limit: int = 10,
    ) -> List[Dict]:
        """
        Hybrid search combining vector and BM25.

        Args:
            query: Text query for BM25
            vector: Query vector
            alpha: Balance between vector (1.0) and keyword (0.0)
            limit: Number of results
        """
        collection = self.client.collections.get(self.collection_name)

        results = collection.query.hybrid(
            query=query,
            vector=vector,
            alpha=alpha,
            limit=limit,
        ).do()

        return [
            {
                "id": str(obj.uuid),
                "properties": obj.properties,
                "score": obj.metadata.score,
            }
            for obj in results.objects
        ]

    def _build_filter(self, filters: Dict) -> Filter:
        """Build Weaviate filter from dict."""
        # Simple single-condition filter
        if "property" in filters:
            return Filter.by_property(filters["property"]).equal(filters["value"])

        # Complex filters would need recursive building
        return None

    def close(self):
        """Close the client connection."""
        self.client.close()
```

```python
# Qdrant Implementation
from qdrant_client import QdrantClient
from qdrant_client.models import (
    Distance,
    VectorParams,
    PointStruct,
    Filter,
    FieldCondition,
    MatchValue,
    SearchParams,
    HnswConfigDiff,
)
from typing import List, Dict, Any, Optional
import uuid


class QdrantVectorStore:
    """Production Qdrant vector store wrapper."""

    def __init__(
        self,
        url: str = "localhost",
        port: int = 6333,
        collection_name: str = "documents",
        api_key: Optional[str] = None,
    ):
        self.client = QdrantClient(
            url=url,
            port=port,
            api_key=api_key,
        )
        self.collection_name = collection_name

    def create_collection(
        self,
        dimension: int,
        distance: str = "cosine",
        on_disk: bool = False,
        hnsw_config: Optional[Dict] = None,
    ):
        """Create collection with configuration."""
        distance_map = {
            "cosine": Distance.COSINE,
            "euclidean": Distance.EUCLID,
            "dot": Distance.DOT,
        }

        vectors_config = VectorParams(
            size=dimension,
            distance=distance_map.get(distance, Distance.COSINE),
            on_disk=on_disk,
        )

        hnsw = None
        if hnsw_config:
            hnsw = HnswConfigDiff(
                m=hnsw_config.get("m", 16),
                ef_construct=hnsw_config.get("ef_construct", 100),
                full_scan_threshold=hnsw_config.get("full_scan_threshold", 10000),
            )

        self.client.create_collection(
            collection_name=self.collection_name,
            vectors_config=vectors_config,
            hnsw_config=hnsw,
        )

    def upsert(
        self,
        ids: List[str],
        vectors: List[List[float]],
        payloads: Optional[List[Dict]] = None,
        batch_size: int = 100,
    ) -> int:
        """Upsert vectors with payloads."""
        points = []
        for i, (id_, vector) in enumerate(zip(ids, vectors)):
            payload = payloads[i] if payloads else {}
            points.append(PointStruct(
                id=id_ if isinstance(id_, int) else str(uuid.uuid5(uuid.NAMESPACE_DNS, id_)),
                vector=vector,
                payload=payload,
            ))

        # Batch upsert
        for i in range(0, len(points), batch_size):
            batch = points[i:i + batch_size]
            self.client.upsert(
                collection_name=self.collection_name,
                points=batch,
            )

        return len(points)

    def search(
        self,
        vector: List[float],
        limit: int = 10,
        filter_conditions: Optional[List[Dict]] = None,
        score_threshold: Optional[float] = None,
        with_payload: bool = True,
        with_vectors: bool = False,
    ) -> List[Dict]:
        """Search with optional filtering."""
        query_filter = None
        if filter_conditions:
            conditions = [
                FieldCondition(
                    key=cond["field"],
                    match=MatchValue(value=cond["value"]),
                )
                for cond in filter_conditions
            ]
            query_filter = Filter(must=conditions)

        results = self.client.search(
            collection_name=self.collection_name,
            query_vector=vector,
            limit=limit,
            query_filter=query_filter,
            score_threshold=score_threshold,
            with_payload=with_payload,
            with_vectors=with_vectors,
            search_params=SearchParams(hnsw_ef=128, exact=False),
        )

        return [
            {
                "id": str(hit.id),
                "score": hit.score,
                "payload": hit.payload if with_payload else None,
                "vector": hit.vector if with_vectors else None,
            }
            for hit in results
        ]

    def search_batch(
        self,
        vectors: List[List[float]],
        limit: int = 10,
    ) -> List[List[Dict]]:
        """Batch search for multiple queries."""
        from qdrant_client.models import SearchRequest

        requests = [
            SearchRequest(vector=v, limit=limit)
            for v in vectors
        ]

        results = self.client.search_batch(
            collection_name=self.collection_name,
            requests=requests,
        )

        return [
            [{"id": str(hit.id), "score": hit.score, "payload": hit.payload} for hit in batch]
            for batch in results
        ]

    def get_collection_info(self) -> Dict:
        """Get collection statistics."""
        info = self.client.get_collection(self.collection_name)
        return {
            "vectors_count": info.vectors_count,
            "points_count": info.points_count,
            "status": info.status,
            "config": {
                "dimension": info.config.params.vectors.size,
                "distance": str(info.config.params.vectors.distance),
            },
        }
```

## Best Practices

### Index Selection

- **HNSW**: Best for most use cases, good recall/speed balance
- **IVF**: Better for very large datasets with memory constraints
- **Flat**: Use only for small datasets or exact search requirements
- **PQ**: When memory is critical, accept some accuracy loss

### Performance Optimization

```python
# Batch operations for efficiency
def batch_embed_and_store(texts: List[str], batch_size: int = 32):
    """Efficient batch processing."""
    for i in range(0, len(texts), batch_size):
        batch = texts[i:i + batch_size]
        embeddings = embedding_model.encode(batch)
        vector_store.upsert(
            ids=[f"doc_{i+j}" for j in range(len(batch))],
            vectors=embeddings.tolist(),
            payloads=[{"text": t} for t in batch],
        )

# Use async for I/O bound operations
async def search_multiple_namespaces(query_vector, namespaces):
    """Search across namespaces concurrently."""
    tasks = [
        search_namespace(query_vector, ns)
        for ns in namespaces
    ]
    results = await asyncio.gather(*tasks)
    return merge_results(results)
```

### Filtering Strategies

- Pre-filter for highly selective conditions
- Post-filter for broad vector search with refinement
- Use indexed metadata fields
- Avoid complex nested filters on large datasets

### Scaling

- Use namespaces/partitions for multi-tenancy
- Implement sharding for very large datasets
- Cache frequent queries
- Monitor query latency percentiles

You design and implement production vector database systems with optimal indexing, filtering, and scaling strategies.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…