AnyLearn
All lessons
Computer Scienceintermediate

The Inverted Index, and Why Analysis Decides Everything

Search does not scan documents; it looks up precomputed answers. This lesson builds the inverted index from first principles, then covers the pipeline that feeds it: tokenization, normalisation, stemming and synonyms, and why an analysis mistake made at index time cannot be fixed at query time. Includes the classic failure where a product SKU becomes unfindable.

Updated · AI-authored, review-gated · how lessons are made

Not signed in: your progress and quiz score won't be saved.
Progress1 / 7

Search is a lookup, not a scan

The naive way to find documents containing "tomato" is to read every document and check. At a million documents that is a million reads per query, and search engines answer in milliseconds, so that is not what happens.

What happens is the same trick as the index at the back of a book: precompute, for every term, the list of documents containing it. At query time, finding "tomato" is one lookup that returns a ready-made list.

Definition: an inverted index maps each term to its postings list: the ids of the documents containing that term, usually with extra per-document detail such as how often the term occurs and at which positions.

The word inverted is the point. A document is naturally a mapping from one id to many words. Search needs the inverse: from one word to many ids. Building and maintaining that inversion, compactly and updatably, is what Lucene and every engine built on it, Elasticsearch, OpenSearch, Solr, spend most of their engineering on.

Everything else in search, scoring, phrase matching, filtering, is machinery layered on top of postings lists. Get comfortable with the lists and the rest of the course has somewhere to stand.

Full lesson text

All 7 steps on one page, for reading, reference, and search.

Show

1. Search is a lookup, not a scan

The naive way to find documents containing "tomato" is to read every document and check. At a million documents that is a million reads per query, and search engines answer in milliseconds, so that is not what happens.

What happens is the same trick as the index at the back of a book: precompute, for every term, the list of documents containing it. At query time, finding "tomato" is one lookup that returns a ready-made list.

Definition: an inverted index maps each term to its postings list: the ids of the documents containing that term, usually with extra per-document detail such as how often the term occurs and at which positions.

The word inverted is the point. A document is naturally a mapping from one id to many words. Search needs the inverse: from one word to many ids. Building and maintaining that inversion, compactly and updatably, is what Lucene and every engine built on it, Elasticsearch, OpenSearch, Solr, spend most of their engineering on.

Everything else in search, scoring, phrase matching, filtering, is machinery layered on top of postings lists. Get comfortable with the lists and the rest of the course has somewhere to stand.

2. From documents to postings

Take three tiny documents and build the index by hand.

Document 1: "red tomato soup". Document 2: "tomato salad". Document 3: "red wine".

Each document is broken into terms, and each term accumulates its postings. The result is a dictionary of terms, each pointing at a sorted list of document ids.

Queries compose by set operations on these lists. "red AND tomato" intersects the two postings lists, giving document 1. "red OR tomato" unions them. Sorted lists make intersection fast, walk both in step, and engines add skip structures so that intersecting a rare term's short list against a common term's long one can leap through the long list rather than crawl it.

Two details in the postings carry most of later lessons. The term frequency per document feeds scoring: a document mentioning tomato five times probably cares more about tomatoes. And the positions enable phrase queries: "tomato soup" as a phrase requires the terms adjacent and in order, which only position data can check.

flowchart LR
A["Doc 1: red tomato soup"] --> D["Index"]
B["Doc 2: tomato salad"] --> D
C["Doc 3: red wine"] --> D
D --> E["red: 1, 3"]
D --> F["tomato: 1, 2"]
D --> G["soup: 1"]
D --> H["salad: 2"]
D --> I["wine: 3"]

3. Analysis: the pipeline that makes terms

The index stores terms, and terms are manufactured. Raw text passes through an analysis pipeline before anything reaches a postings list, and each stage is a policy decision:

StageWhat it doesExample
Character filteringCleans the raw streamStrip HTML, map curly quotes
TokenizationSplits text into candidate tokens"red-hot soup!" becomes red, hot, soup
LowercasingMerges case variantsSoup and soup become one term
Stop word removalDrops ultra-common words, if configuredthe, of, and vanish
Stemming or lemmatisationMerges word formsrunning, runs, ran become run
SynonymsExpands or maps equivalentslaptop adds notebook

The output is the term stream that gets indexed, and none of the original spelling survives except as stored, unsearched, source text.

Why so aggressive? Recall. A user typing "run" expects documents saying "running". Every merge in the pipeline is a bet that two surface forms mean the same thing, trading precision, the ability to distinguish them, for recall, the ability to match across them. The whole craft of analysis configuration is placing those bets differently for different fields.

4. The symmetry rule

The analysis pipeline runs twice: once at index time over documents, once at query time over what the user typed. The two runs must be compatible, and the reason is mechanical, not conventional.

Matching happens by exact term equality in the index. If indexing stems "running" down to "run" but the query pipeline leaves "running" intact, the query term "running" is looked up against an index that only contains "run": zero results, silently. The document is there; the vocabulary no longer matches.

Gotcha: analysis is baked into the index at write time. Changing the analyzer does nothing for documents already indexed under the old one; the postings were built from the old terms and cannot be reinterpreted. An analyzer change is a reindex of everything, which for a large corpus is a project, not a setting. This is why search teams agonise over analysis choices up front and why blue-green reindexing infrastructure exists.

Deliberate asymmetry does exist: applying synonyms only at query time, for instance, so the synonym list can be updated without reindexing, at some cost in scoring accuracy. That is a considered exception that proves the rule: the two pipelines are one design with two entry points, never two independent configurations.

5. The SKU that vanished

The classic production incident in this area involves an identifier, and it is worth walking precisely because every e-commerce and B2B search hits it.

Predict first

A product with SKU "XR-2000-B" is in the index. A customer pastes exactly "XR-2000-B" into search: zero results. The product page exists, the index is healthy. What happened?

This is also the first appearance of this course's recurring theme: the lexical machinery is exact by nature, which makes it wonderful for identifiers and terrible at knowing that laptop and notebook are the same thing. That trade is lesson three's subject.

6. Fields, mappings, and the document model

Real documents are not one blob of text; they are structured: a title, a body, a brand, a price, tags, an SKU. Engines index each field separately, with its own analysis, and this is where schema design earns its keep.

The working vocabulary, in Elasticsearch terms that map directly onto Lucene:

  • text fields go through full analysis and feed relevance scoring: titles, descriptions, reviews.
  • keyword fields are indexed as single exact terms: SKUs, status values, brand names used for filtering and aggregation.
  • numeric, date and boolean fields use specialised structures built for ranges rather than postings-list lookups.
  • The same source value can be indexed multiple ways at once, a brand as text for matching and as keyword for the facet sidebar, because matching and filtering genuinely need different representations.

Two schema rules with outsized payoff. Decide per field what question it answers, match it, filter it, sort it, facet it, and index for exactly those, because every representation costs write throughput and disk. And treat mapping changes with the same respect as analyzer changes: most of them also require a reindex, for the same baked-at-write-time reason.

7. What the index costs, and when it pays

The inverted index is a bet that reads outnumber writes, and it is worth making the bet's terms explicit.

Every document write fans out into updates across every term the document contains, and engines batch these into immutable segments that background processes merge, which is why search engines describe themselves as near-real-time: a written document becomes searchable after the next refresh, typically a second or so, not instantly.

In exchange, reads are spectacular: a query touches only the postings lists of its query terms, each compressed, cache-friendly and skip-listed, regardless of how many millions of documents sit in the corpus.

The bet fails in recognisable situations. Write-dominated workloads with rare queries pay indexing costs for nothing, a log pipeline that mostly archives should think twice about full indexing. Point lookups by id need a key-value store, not postings. Analytical scans over whole columns want columnar storage. The mature architecture pattern is unbundled: a primary database owns the truth, and the search engine holds a derived, denormalised copy fed by change streams, rebuildable at will, which is exactly the posture the reindex-heavy operations above demand anyway.

Check your understanding

The lesson ends with a 5-question quiz. Take it in the player above to see your score.

  1. What does an inverted index store?
    • A mapping from each document to the list of its terms
    • A compressed copy of every document for fast scanning
    • A mapping from each term to the list of documents containing it, with frequencies and positions
    • A precomputed answer for every possible query
  2. Why must index-time and query-time analysis be compatible?
    • Matching is exact term equality, so a query analysed differently produces terms that do not exist in the index
    • The engine caches queries by analyzer version
    • Incompatible analyzers double storage requirements
    • Query analysis is only used for highlighting
  3. Why does changing an analyzer require reindexing existing documents?
    • The engine licence ties analyzers to index creation
    • Analysis output is baked into the postings at write time and cannot be reinterpreted afterwards
    • Old documents are stored compressed and cannot be read
    • Analyzers only run on the primary shard
  4. A search for the exact SKU "XR-2000-B" returns zero results though the product is indexed. What is the most likely cause?
    • The index needs a segment merge
    • The SKU exceeds the maximum term length
    • Stop word removal dropped the SKU
    • The tokenizer split the identifier into fragments at index time, so the whole value exists nowhere as a term
  5. When is an inverted index the wrong tool?
    • When documents contain more than one language
    • When queries use more than three terms
    • For write-dominated workloads with rare queries, point lookups by id, or full-column analytical scans
    • When the corpus exceeds ten million documents

Related lessons

Computer Science
intermediate

BM25: How Lexical Relevance Is Actually Computed

Matching finds candidates; scoring orders them, and the ordering is the product. This lesson builds BM25, the default ranking function of Lucene, Elasticsearch and OpenSearch, from its three ingredients: rare terms count more, repeated terms saturate, and long documents get discounted. With the formula, the two tuning knobs, and the saturation curve computed by hand.

7 steps·~11 min
Computer Science
intermediate

Measuring Relevance: Judgments, NDCG, and the Click Trap

Search quality arguments end when there is a number, and begin again over whether the number is honest. This lesson builds offline evaluation from its atoms: a judgment set, precision and recall at k, MRR for known-item queries, and NDCG computed by hand for graded relevance. Then the online half: clicks, position bias, and why the top result gets clicked even when it is wrong.

7 steps·~11 min
Computer Science
intermediate

Lexical Meets Vector: Hybrid Search and Rank Fusion

Vector search did not replace keyword search, because the two fail in opposite places: BM25 cannot see that laptop and notebook mean the same thing, and embeddings cannot see that SKU-4471-B is not approximately anything. This lesson maps the two failure surfaces, then builds the production answer: run both retrievers and fuse the rankings, with reciprocal rank fusion done by hand.

7 steps·~11 min
AI
advanced

Turning Sound Into Tokens

Before a model can process speech it has to be discretised, and audio resists that harder than text does. This lesson covers why raw waveforms are the wrong representation, how neural audio codecs learn a discrete one, what residual vector quantization actually does, and the arithmetic that governs every speech model: a minute of talking is around 195 text tokens or 36,000 audio tokens.

9 steps·~14 min