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.
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, it also serves Jina's dense multilingual and multimodal embedding models and its cross-encoder rerankers 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. (How that web is built, why it has layers, and its one crucial tuning dial fill an essay of their own: HNSW: the graph that finds meaning.) Drag the query, then turn on the graph:
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 a graph walk is only fast when the vectors it compares sit in memory. 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:
"Search generously, then re-check" deserves its own dials, because oversampling is the mechanism that buys BBQ's memory savings back its accuracy. Compressed scores are noisy, so the true best answers are probably near the top of the compressed ranking, but not exactly at it. Fetch extra candidates, rescore them exactly, keep the winners:
The graph is not the only layout either. Since 9.4, where the license allows it, Elasticsearch defaults new vector fields to bbq_disk: the same one-bit compression, but vectors grouped into clusters (a variant of k-means) instead of linked in a graph. Without that license the default remains an HNSW graph with BBQ above 384 dimensions.
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.
Where the vectors come from, the models, the chunking of long documents, sparse versus dense embeddings, late interaction, rerankers, is a craft of its own: Semantic search in practice.
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:
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.