A quick and easy way to do this is to index both the original and lowercased
versions of each word. If the user searches for an all-lowercase word, it acts
as a case-insensitive search, but if they search for a word with any uppercase
characters, it acts as a case-sensitive search:

Use the whoosh.analysis.NgramWordAnalyzer as the analyzer for the
field you want to search as the user types. You can save space in the index by
turning off positions in the field using phrase=False, since phrase
searching on N-gram fields usually doesn’t make much sense:

# For example, to search the "title" field as the user typesanalyzer=analysis.NgramWordAnalyzer()title_field=fields.TEXT(analyzer=analyzer,phrase=False)schema=fields.Schema(title=title_field)

See the documentation for the NgramWordAnalyzer class
for information on the available options.

Usually, however, the exact number of documents that match the query is not
known, because the searcher can skip over blocks of documents it knows won’t
show up in the “top N” list. If you call len(results) on a query where the
exact length is unknown, Whoosh will run an unscored version of the original
query to get the exact number. This is faster than the scored search, but may
still be noticeably slow on very large indexes or complex queries.

# Use terms=True to record term matches for each hitresults=searcher.search(myquery,terms=True)forhitinresults:# Which terms matched in this hit?print("Matched:",hit.matched_terms())# Which terms from the query didn't match in this hit?print("Didn't match:",myquery.all_terms()-hit.matched_terms())

# Check if the "content" field of document 500 contains the term "wobble"# Without term vectors, skipping through list...postings=searcher.postings("content","wobble")postings.skip_to(500)returnpostings.id()==500# ...or the slower but easier waydocset=set(searcher.postings("content","wobble").all_ids())return500indocset# If field has term vectors, skipping through list...vector=searcher.vector(500,"content")vector.skip_to("wobble")returnvector.id()=="wobble"# ...or the slower but easier waywordset=set(searcher.vector(500,"content").all_ids())return"wobble"inwordset