Friday, August 28, 2026
HomeData ScienceVector Databases & Embeddings – Semantic Search in Python 2026

Vector Databases & Embeddings – Semantic Search in Python 2026

Table of Content

Traditional keyword search matches exact words. Semantic search understands meaning — a query for “affordable cars” finds results about “budget vehicles” even if those exact words don’t appear. The technology behind semantic search is vector embeddings and vector databases. In 2026, these are essential building blocks for RAG systems, recommendation engines, and document similarity search. This guide covers everything you need to know.

What Are Embeddings?

An embedding is a dense numerical vector that represents the meaning of text (or images, audio, etc.) in a high-dimensional space. Similar texts have similar vectors — measured by cosine similarity or dot product. The embedding model (like all-MiniLM-L6-v2) converts raw text into a 384-dimensional float vector. Similar sentences like “the cat sat on the mat” and “a feline rested on the rug” will have vectors very close together, even with no shared words.

Generating Embeddings with Sentence-Transformers

brown wooden blocks on white table
Photo by Brett Jordan on Unsplash
pip install sentence-transformers
from sentence_transformers import SentenceTransformer
import numpy as np

model = SentenceTransformer('all-MiniLM-L6-v2')  # 384 dimensions, fast

sentences = [
    "Machine learning is a subset of artificial intelligence.",
    "ML algorithms learn patterns from data.",
    "Python is great for cooking recipes.",
]

embeddings = model.encode(sentences, normalize_embeddings=True)
print(embeddings.shape)  # (3, 384)

# Cosine similarity (high = similar)
from sklearn.metrics.pairwise import cosine_similarity
sim_matrix = cosine_similarity(embeddings)
print(f"Sentence 0 vs 1: {sim_matrix[0][1]:.3f}")  # ~0.82 (similar)
print(f"Sentence 0 vs 2: {sim_matrix[0][2]:.3f}")  # ~0.12 (different)
pip install faiss-cpu  # or faiss-gpu for GPU
import faiss
import numpy as np

# Create index (Inner Product = cosine similarity for normalized vectors)
dim   = 384
index = faiss.IndexFlatIP(dim)  # exact search

# Add document embeddings
corpus_embeddings = model.encode(corpus_texts, normalize_embeddings=True)
index.add(corpus_embeddings.astype(np.float32))

# Search
query     = "how does gradient descent work?"
query_emb = model.encode([query], normalize_embeddings=True)

distances, indices = index.search(query_emb.astype(np.float32), k=5)
for i, idx in enumerate(indices[0]):
    print(f"[{distances[0][i]:.3f}] {corpus_texts[idx][:100]}")

# For large datasets, use approximate search (much faster)
index = faiss.IndexIVFFlat(faiss.IndexFlatIP(dim), dim, 100)
index.train(corpus_embeddings.astype(np.float32))
index.add(corpus_embeddings.astype(np.float32))
index.nprobe = 10  # number of clusters to search

ChromaDB – Easy Local Vector Store

pip install chromadb
import chromadb
from chromadb.utils import embedding_functions

client = chromadb.PersistentClient(path="./chroma_store")

# Use sentence-transformers as embedding function
ef = embedding_functions.SentenceTransformerEmbeddingFunction(
    model_name="all-MiniLM-L6-v2")

collection = client.get_or_create_collection(
    name="knowledge_base", embedding_function=ef)

# Add documents (embeddings computed automatically)
collection.add(
    documents=["Python is a programming language.",
                "Machine learning requires data.",
                "Deep learning uses neural networks."],
    metadatas=[{"source": "intro.pdf", "page": 1},
               {"source": "ml_book.pdf", "page": 12},
               {"source": "dl_guide.pdf", "page": 5}],
    ids=["doc1", "doc2", "doc3"]
)

# Query
results = collection.query(
    query_texts=["what programming language for AI?"],
    n_results=2,
    include=["documents", "metadatas", "distances"])

for doc, meta, dist in zip(results['documents'][0],
                            results['metadatas'][0],
                            results['distances'][0]):
    print(f"[{1-dist:.3f}] {doc} | Source: {meta['source']}")

Pinecone – Managed Vector Database

pip install pinecone-client
from pinecone import Pinecone, ServerlessSpec

pc    = Pinecone(api_key="YOUR_API_KEY")
index = pc.Index("my-knowledge-base")

# Upsert vectors with metadata
vectors = [
    {"id": f"doc_{i}",
     "values": emb.tolist(),
     "metadata": {"text": text, "source": source}}
    for i, (text, emb, source) in enumerate(zip(texts, embeddings, sources))
]
index.upsert(vectors=vectors)

# Query
query_emb = model.encode(["best practices for MLOps"])[0].tolist()
results   = index.query(vector=query_emb, top_k=5,
                        include_metadata=True,
                        filter={"source": {"$eq": "mlops_guide.pdf"}})

for match in results['matches']:
    print(f"Score: {match['score']:.3f} | {match['metadata']['text'][:100]}")

Semantic Search Application

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class SearchRequest(BaseModel):
    query: str
    top_k: int = 5

@app.post("/search")
def semantic_search(req: SearchRequest):
    query_emb = model.encode([req.query], normalize_embeddings=True)
    results   = collection.query(
        query_embeddings=query_emb.tolist(), n_results=req.top_k)
    return {
        "results": [
            {"text": doc, "score": round(1 - dist, 3), **meta}
            for doc, dist, meta in zip(
                results["documents"][0],
                results["distances"][0],
                results["metadatas"][0])
        ]
    }

Choosing a Vector Database

FAISS is best for local, in-memory search where you control the hardware and need maximum performance — it’s used by Meta internally. ChromaDB is easiest for local development and prototyping (zero infrastructure setup). Pinecone and Weaviate are managed services best for production where you don’t want to manage infrastructure. Qdrant is a strong self-hosted option if you want full control in production. For most projects: start with ChromaDB locally, then migrate to Pinecone or Qdrant for production.

Conclusion

Vector databases and embeddings are foundational infrastructure for modern AI applications. Every RAG system, semantic search engine, recommendation engine, and duplicate detection pipeline is built on these primitives. The good news: with sentence-transformers and ChromaDB, you can have a working semantic search system running locally in under 30 minutes. Master these building blocks and you’ll be equipped to build the AI-powered products that define the current era.

Leave feedback about this

  • Rating

Durgesh Kekare
Durgesh Kekarehttps://www.dataexpertise.in
Durgesh Kekare is a data science educator and founder of DataExpertise.in. With expertise in Python, machine learning, and analytics, he helps 10,000+ learners break into data careers.

Latest Posts

List of Categories