The one Whoosh setting that decides whether search actually works: the analyzer
You wire up a search index, add your documents, type a query you know should match... and get zero results. The document is right there. The word is right there. What gives? Nine times out of ten the answer is the analyzer — the small pipeline that decides how text becomes searchable tokens. It runs when you index and when you query, and if the two sides don't agree on what a "word" is, nothing matches. Whoosh is a pure-Python full-text search library ( pip install whoosh3 ), and one of its quietly great features is that this pipeline is completely yours to compose. Let me show you what's happening under the hood and how to bend it to your data. An analyzer is just tokenizer + filters Every analyzer starts with a tokenizer (splits a string into tokens) and then chains zero or more filters (transform, drop, or add tokens). Whoosh spells this composition with the | operator, which reads exactly like a Unix pipe: from whoosh.analysis import RegexTokenizer , LowercaseFilter , StopFilter analyzer = RegexTokenizer () | LowercaseFilter () | StopFilter () print ([ t . text for t in analyzer ( " The quick brown FOX jumps " )]) # ['quick', 'brown', 'fox', 'jumps'] Notice what happened: The was lowercased and then dropped as a stop word, FOX became fox . You can run an analyzer directly on a string like this — no index required — which makes debugging your search a hundred times easier. When results surprise you, the first thing to do is feed the text through the analyzer and look at the tokens . Why the default sometimes "loses" your documents Here's the classic failure, reproduced end to end. Two documents, one query, two analyzers: from whoosh.fields import Schema , TEXT , ID from whoosh.analysis import StandardAnalyzer , StemmingAnalyzer from whoosh.filedb.filestore import RamStorage from whoosh.qparser import QueryParser for name , ana in [( " standard " , StandardAnalyzer ()), ( " stemming " , StemmingAnalyzer ())]: schema = Schema ( id = ID ( stored = True ), body = TEX