build-a-search-engine / lesson-34.md
Lesson 34 · Querying

The complete search library

Today you exercise the whole library through its public API in one usage example - add documents, then run free-text, boolean, and phrase queries against them. This is the deliverable the project has been building toward.

The goal

Drive the finished index end to end - add documents and answer free-text, boolean, and phrase queries.

Start here - the target
TO DO
Scenario: The library works end to end
Givenan index with ("d1", "the quick brown fox"), ("d2", "the lazy brown dog"), and ("d3", "a quick brown cat") added
Whenyou use the public API
Thensearch("quick fox") ranks "d1" first, and the phrase ["quick", "brown"] matches ["d1", "d3"]
Andthe boolean query "brown AND NOT dog" gives ["d1", "d3"]
Background

Thirty-three lessons of pieces come together here. There is nothing new to build: today is about seeing the finished library answer real questions through the API a user would call. Add a few documents, then ask for them three different ways - ranked free text, a strict phrase, and a boolean expression - and watch each return exactly the right documents.

search("quick fox") ranks d1 on top because it matches both words; the phrase quick brown finds only the documents where those words are truly adjacent; and brown AND NOT dog keeps the brown documents while subtracting the one about a dog. That is a working search engine in the spirit of Lucene - an analyzer, an inverted index, BM25 ranking, and a query layer - small enough to hold in your head, and entirely yours.

Make it work
idx = SearchIndex()
idx.add("d1", "the quick brown fox")
idx.add("d2", "the lazy brown dog")
idx.add("d3", "a quick brown cat")
idx.search("quick fox") # -> ["d1", ...]
idx.phrase(["quick", "brown"]) # -> ["d1", "d3"]
idx.eval_bool(parse_bool("brown AND NOT dog")) # -> ["d1", "d3"]
Further Reading

Manning, Introduction to Information Retrieval - ch. 1-8, in review.

CheckpointDONE
The full search library - add, rank, boolean, phrase - works through one coherent API. Commit and stop here.