CodeRigor

LESSON

An inverted index with counts and document lengths

Map each term to the documents that contain it, count occurrences per document, and retain empty documents in corpus statistics.

Scanning every note for every query is a useful first implementation, but it repeats work. An inverted index turns the direction around: look up a term, then visit the documents known to contain it. The index is derived data. Its IDs must still refer to the validated snapshot, and its terms must come from the shared tokenizer.

We keep two maps. lengths records the total number of body tokens for every document. postings records each term’s positive occurrence count in each containing document. Titles remain display metadata. A note titled red with an empty body has length zero and contributes no red posting.

Turn the lookup direction around
start / 3
Each posting lists its containing documents and counts; the two terms branch from one corpus.
Turn the lookup direction around
Each posting lists its containing documents and counts; the two terms branch from one corpus.

A posting count is not a Boolean membership flag. When a token repeats, increment that document’s count. Also keep token length separate from distinct vocabulary size. In red red blue, length is three, the vocabulary has two members, and red occurs twice. The ranking lesson uses all three ideas for different purposes.

Python
from collections import Counter
tokens = 'red red blue'.split()
print(len(tokens), dict(Counter(tokens)))
print(len(set(tokens)))

An empty document still belongs in lengths. Later N means all documents in the corpus, whereas a term’s document frequency counts only the IDs in its posting map. Removing empty records silently changes rarity weights. The corpus may be empty too; in that case both maps are empty and ranking has nothing to visit.

Build fresh maps on every call. Sorting outer term keys and inner ID keys makes exported JSON and fixtures easy to compare. Sorting is a presentation and reproducibility choice; it is separate from the relevance ranking of results.

Three counts, three meanings
start / 3
Document length counts occurrences, document frequency counts containing IDs, and N counts all documents.
Three counts, three meanings
Document length counts occurrences, document frequency counts containing IDs, and N counts all documents.
Python
lengths = {'a': 0, 'b': 3}
red_posting = {'b': 2}
print('N', len(lengths))
print('df', len(red_posting))
print('tf', red_posting['b'])

The build supplies validation and tokenization so you can focus on count ownership. Check repeated terms in one document, the same term in several documents, an empty body, an empty corpus and a second independent call. For larger collections this in-memory representation is only a starting point: disk layouts, compression and incremental updates need additional contracts and measurements.

Watch & read

Free lectures, talks and readings that cover this skill from another angle. All resources →

Use the text representation and TF–IDF sections. The lab states its own exact tokenization and weighting conventions.