The vector database

The Elasticsearch essays · August 2026

Everything else in this series matches and counts symbols. But "the checkout is broken" and "customers can't complete purchases" share no symbols at all, and no inverted index will ever connect them. This essay is about the leap past symbols: vectors, the graphs that navigate them, the compression that makes them affordable, and the fusion that lets the lexical and semantic judges vote together.

1 · Meaning: the vector store

Lexical search matches and counts symbols. But "the checkout is broken" and "customers can't complete purchases" share no symbols at all. Modern language models offer an exit: they convert text into a list of numbers, an embedding, such that similar meanings land near each other. Search-by-meaning becomes geometry: embed the query, find the nearest neighbors.

Where do the embeddings come from? Elasticsearch runs the models itself. Its own ELSER model produces sparse vectors, a bag of weighted concept-words, interpretable and served by the familiar inverted index; and since acquiring Jina AI, whose open frontier models are among the best in class, it also serves dense multilingual and multimodal embeddings (jina-embeddings-v3) and cross-encoder rerankers natively through its inference service. Map a field as semantic_text and the machine embeds every document, and every query, automatically.

Finding nearest neighbors by measuring every distance would be a full scan, the very thing this machine exists to avoid. So vectors get an index too: HNSW, a web of neighbor links a query can greedily hop across. Drag the query, then turn on the graph:

3
Drag the dark query point. With the graph on, the orange path is the greedy walk from a fixed entry point: a handful of hops instead of 52 distance checks.
Now add a filter and drag the query far from the matching cluster: the answers stay within the filter, however far you roam. Filtering after a vector search can starve you of results; Elasticsearch filters during the graph walk instead, traversing non-matching points but never returning them.

There is one problem left, and it's the one that decides whether vector search is affordable: memory. A single 1024-dimension embedding in full precision costs 4 KB, and HNSW wants vectors in RAM. A hundred million documents would need 400 GB for the vectors alone. Elasticsearch's answer, and a place where it has pushed the state of the art, is BBQ, Better Binary Quantization: compress each dimension to roughly one bit, carrying corrective statistics so the compressed comparisons stay honest:

RAM for 100M vectors
per vector
compression
recall, with rescoring
float32int8BBQ · 1 bit
Drag precision down and watch the same 24 dimensions coarsen: full floats, then small integers, then single bits. Memory for 100 million vectors collapses from 410 GB to 14 GB. The trick that keeps quality high: search the compressed vectors generously (oversample), then re-check the finalists against exact values. BBQ is now the default for large vectors.

A database under the vectors

Compression and clever graphs are what make vector search possible; what makes it usable is everything this machine already was. A dedicated vector index holds vectors; Elasticsearch holds vectors next to the document they came from, so the filtered search you just tried above, "similar to this, but only in checkout, only this week", is one query, with the filters answered by the keyword and BKD structures of the earlier chapters, honored during the graph walk. Vectors here are replicated by the same shards, aged by the same lifecycle policies, secured by the same permissions, aggregated by the same engine. A vector store bolted onto your stack is another database to operate; this one is a column in a database you already have.

The model side is equally built-in. Map a field as semantic_text and Elasticsearch handles the machinery nobody enjoys: long documents are chunked automatically, each chunk embedded and searched, so a relevant paragraph is found even inside a hundred-page manual. The embeddings can be sparse (ELSER, interpretable weighted terms served by the inverted index) or dense (the Jina models, multilingual and multimodal, so a text query can find an image). For the highest-precision use cases there is even late interaction: storing one vector per token and comparing query and document token-by-token, a technique the rank_vectors field exists to serve. And the choice of geometry itself, cosine angle, dot product, Euclidean distance, is a mapping option, one line.

2 · Hybrid search: two judges are better than one

So the machine now has two ways to rank text: the lexical judge (BM25), unbeatable on exact words, product codes, error strings; and the semantic judge (vectors), which sees paraphrase and intent but can be vague about specifics. Which should you use? The honest answer is both, and the way Elasticsearch combines them is almost embarrassingly simple: reciprocal rank fusion. Ignore the incomparable scores entirely; look only at each document's rank in each list, and award it 1/(k+rank) points per list:

Lexical · BM25
Semantic · vectors
Fused · RRF
60
The orange document tops neither list, but it's the only one both judges respect, and fusion finds it. Small k trusts the top ranks aggressively; large k flattens the vote.

For the final polish, the top of the fused list can be handed to a reranker, a heavier model (the Jina rerankers, in Elasticsearch's case) that reads query and document together and re-orders the finalists with far more care than any first-pass ranking could afford. Cheap judges to nominate candidates, an expensive judge for the podium, the machine's usual economics, applied to relevance itself.

The filters honored during the graph walk come from the search essay's structures; how all the stores answer one query together is the subject of The machine, whole.