Learn  /  Guides

Embeddings and vector search for analysts: a practical guide with EmbeddingGemma 2, DuckDB and PostgreSQL

Search your tickets, reviews and documents by meaning, not keywords, on your own laptop. What embeddings are, and a working example in Python, DuckDB and PostgreSQL.

Guide11 min readUpdated 28 October 2026
AIPythonDatabases
All guides and cheat sheets

Keyword search finds "refund" but misses "I want my money back". Embeddings fix that: they turn text, and now images and audio, into lists of numbers where similar meanings sit close together. They power AI search, chatbots that answer from your documents, duplicate detection and clustering. In October Google released EmbeddingGemma 2, a free, open model small enough to run on a laptop or phone. This guide explains the idea and walks through a complete example with tools analysts already use.

740MParameters270M for text only
768Dimensionstruncate to 512, 256 or 128
8KTokens of contextper input
100+Languagesplus code

Embeddings in one picture

How semantic search works
Your text"I want my money back"
Embedding modelEmbeddingGemma 2
Vector[0.12, -0.08, 0.31, ...]
Similarity searchDuckDB or pgvector
Closest matchesrefund tickets, any wording

Every document is converted to a vector once and stored. At search time, the question is converted too, and the database returns the stored vectors closest to it, usually measured with cosine similarity, a score from -1 to 1 where higher means more similar.

Embedding
A fixed-length list of numbers representing the meaning of an input.
Dimension
The length of that list. EmbeddingGemma 2 produces 768 by default.
Cosine similarity
How closely two vectors point the same way. 1 means identical meaning.
Vector index
A structure such as HNSW that finds near neighbours fast in millions of rows.
RAG
Retrieval-augmented generation: find the most relevant documents with embeddings, then give them to a chatbot to answer from.

Step 1: create embeddings in Python

Install the libraries once with pip install -U sentence-transformers transformers. The first run downloads the model from Hugging Face.

Python
from sentence_transformers import SentenceTransformer

# Text only: skip the vision and audio encoders to save memory (270M parameters)
model = SentenceTransformer(
    "google/embeddinggemma-2",
    config_kwargs={"vision_config": None, "audio_config": None},
)

tickets = [
    "I was charged twice for my order",
    "Can I get my money back for a broken item?",
    "How do I change my delivery address?",
    "The app crashes when I open my basket",
]

# Documents use the "Document" prompt; 256 dimensions; unit length for cosine
doc_vecs = model.encode(tickets, prompt_name="Document",
                        truncate_dim=256, normalize_embeddings=True)

query_vec = model.encode("refund request", prompt_name="SearchQuery",
                         truncate_dim=256, normalize_embeddings=True)

print(model.similarity(query_vec, doc_vecs))  # highest score = best match
Python
import duckdb

con = duckdb.connect("tickets.duckdb")
con.execute("CREATE OR REPLACE TABLE tickets (id INT, text VARCHAR, emb FLOAT[256])")
con.executemany("INSERT INTO tickets VALUES (?, ?, ?)",
                [(i, t, v.tolist()) for i, (t, v) in enumerate(zip(tickets, doc_vecs))])

top = con.execute("""
    SELECT text, array_cosine_similarity(emb, ?::FLOAT[256]) AS score
    FROM tickets
    ORDER BY score DESC
    LIMIT 3
""", [query_vec.tolist()]).fetchall()
print(top)

How many dimensions do you need?

EmbeddingGemma 2 is trained so you can keep only the first part of each vector. Shorter vectors mean less storage and faster search, with a small loss in quality. Google's own benchmark results:

Quality vs vector size (MTEB multilingual score, higher is better)
768 dimensions (1x storage)61.4
512 dimensions (0.67x)61.2
256 dimensions (0.33x)60.4
128 dimensions (0.17x)57.9

Axis starts at 50 to show the differences. Source: EmbeddingGemma 2 model card. 768 dimensions is the full size; 256 keeps about 98% of the quality at one third of the storage. 128 is best kept for text-only uses.

What analysts can do with this

  1. 1

    Search support tickets by meaning

    Find every complaint about late deliveries, however it is worded.

  2. 2

    Group open-text survey answers

    Cluster embeddings to discover the themes in thousands of comments in minutes.

  3. 3

    Find duplicates

    Spot near-identical products, customers or tickets that exact matching misses.

  4. 4

    Build a "chat with our docs" assistant

    Retrieve the right paragraphs with embeddings, then let a language model answer from them.

  5. 5

    Keep it private

    Because the model runs locally, sensitive text never leaves your machine.

Check your understanding

1/3What does cosine similarity measure?

2/3What should you do after shortening (truncating) an embedding?

3/3Which pgvector operator gives cosine distance?

Working with Python data tools? See Upgrading to pandas 3.0 and DuckDB 2.0. For which AI models to pair with your search, read The best AI models in October 2026.

Sources: the EmbeddingGemma 2 model card on Hugging Face (google/embeddinggemma-2) and Google DeepMind's announcement (6 October 2026); DuckDB array functions documentation; pgvector documentation. Benchmarks are Google's published results.

Alessandro Ecclesie AgazziWritten by Alessandro Ecclesie Agazzi, analytics engineer in London. Updated 28 October 2026. About me

Found this useful?

New guides and "what's new" explainers on data and AI land here regularly. Follow along on LinkedIn, or share this one with a colleague.