Full-Text Search in MongoDB
MongoDB provides built-in full-text search capabilities through text indexes. A text index tokenizes and stems string content, allowing you to search for words and phrases across one or more fields. This is faster and more capable than using $regex for keyword searches.
Creating a Text Index
A collection can have at most one text index, but it can cover multiple fields:
// Text index on a single field
db.articles.createIndex({ content: "text" })
// Text index on multiple fields
db.articles.createIndex({
title: "text",
content: "text",
tags: "text"
})
// With weights to boost certain fields
db.articles.createIndex(
{ title: "text", content: "text" },
{ weights: { title: 10, content: 1 } }
)Basic Text Search
Use the $text operator with $search to find documents containing specific words:
// Search for documents containing "mongodb" or "tutorial"
db.articles.find({
$text: { $search: "mongodb tutorial" }
})
// Exact phrase search (use escaped quotes)
db.articles.find({
$text: { $search: '"aggregation pipeline"' }
})
// Exclude a term with the minus prefix
db.articles.find({
$text: { $search: "mongodb -deprecated" }
})By default, multiple words are treated as an OR -- the document must contain at least one of the terms.
Text Score and Sorting
MongoDB assigns a relevance score to each matching document. Use $meta: "textScore" to access and sort by this score:
// Return results sorted by relevance
db.articles.find(
{ $text: { $search: "mongodb performance" } },
{ score: { $meta: "textScore" } }
).sort({ score: { $meta: "textScore" } })
// Result includes a "score" field:
// { title: "MongoDB Performance Tips", score: 3.5, ... }
// { title: "Database Performance", score: 1.2, ... }Language Support
Text indexes support language-specific stemming and stop words. You can set the language at the index or query level:
// Create a text index with Spanish language
db.articles.createIndex(
{ content: "text" },
{ default_language: "spanish" }
)
// Search with a specific language
db.articles.find({
$text: {
$search: "base de datos",
$language: "spanish"
}
})
// Disable stemming with "none"
db.articles.find({
$text: {
$search: "running",
$language: "none" // matches "running" exactly, not "run"
}
})Text Search in Aggregation
Combine text search with the aggregation pipeline for advanced filtering and analysis:
db.articles.aggregate([
{ $match: { $text: { $search: "mongodb" } } },
{ $addFields: { score: { $meta: "textScore" } } },
{ $match: { score: { $gt: 2.0 } } },
{ $sort: { score: -1 } },
{ $limit: 10 },
{ $project: { title: 1, score: 1 } }
])Key Takeaways
- A collection can have only one text index, but it can span multiple fields.
- Use
$textwith$searchfor word and phrase matching. - Sort by
textScoreto rank results by relevance. - For more advanced search needs, consider MongoDB Atlas Search with Lucene-based indexes.
Try this query in UnifySQL
Write, optimize, and collaborate on MongoDB queries with AI assistance.
Start Free