Text Indexes
A customer types "hobbits" into the search box. An equality filter needs the exact string "The Hobbit", and a regular expression can't use a normal index efficiently for words in the middle of a title. A text index is built for this: it splits text into words and searches those.
The rule
Index words, not strings:
$textsearches stems, ignores stop words, ORs terms.
db.books.createIndex({ title: "text", author: "text" })
db.books.find({ $text: { $search: "hobbits" } }) // The Hobbit
db.books.find({ $text: { $search: "emma circe" } }) // Emma, Circe
db.books.find({ $text: { $search: "herbert" } }) // Dune (by author)What the index does to each string:
- Splits it into words and ignores case.
- Drops stop words, very common words such as "the", "a" and "and" (per language, English by default).
- Stems words, so "hobbits" and "hobbit" share one entry.
What $search understands:
- Several words are ORed:
"emma circe"matches either. - A quoted phrase must appear as written:
"\"the hobbit\"". - A leading minus excludes:
"miller -dune".
Rank the matches with the relevance score:
db.books.find({ $text: { $search: "dune hobbit" } }, { score: { $meta: "textScore" } })
.sort({ score: { $meta: "textScore" } })Limits: one text index per collection (list every field you need in it), no typo tolerance and no autocomplete. For those, Atlas offers Atlas Search, a separate full-text engine.
The shortcut
To predict a text search, reduce every word to its stem, drop the stop words, then OR what remains.
Split and lower-case
the, hobbits, of, tolkien.
The trap: searching only for a stop word. { $text: { $search: "the" } } returns nothing, even though "The Hobbit" contains "The".
Drills
Answer fast — trust the rule.
How many text indexes can one collection have?
What does { $text: { $search: "dune neuromancer" } } return?
Why does "hobbits" find "The Hobbit"?
What does { $text: { $search: "the" } } return?
Remember
- Index words, not strings:
$textsearches stems, ignores stop words, ORs terms. - Shortcut: stem, drop stop words, OR the rest.
- Trap: one text index per collection, no typo tolerance; reach for Atlas Search when you need more.
