Skip to content

MongoDB - 文本搜索

MongoDB 通过 text 索引提供强大的全文搜索功能。此功能允许您高效地在字符串内容中搜索单词和短语。它包括不区分大小写、支持多种语言和词干提取(例如,搜索 ‘running’ 也会找到 ‘run’)。

首先,您需要在要搜索的字段上定义一个 text 索引。让我们考虑一个博客 posts 集合。

// 插入样本数据
db.posts.insertMany([
{
"_id": 1,
"content": "An introduction to the powerful features of MongoDB.",
"tags": ["mongodb", "database", "nosql"]
},
{
"_id": 2,
"content": "MongoDB text search is a powerful tool for developers.",
"tags": ["search", "full-text", "mongodb"]
},
{
"_id": 3,
"content": "We are exploring advanced database indexing techniques.",
"tags": ["database", "performance"]
}
]);
// 在 'content' 字段上创建文本索引
db.posts.createIndex({ content: "text" });
// 你也可以索引多个字段
// db.posts.createIndex({ content: "text", tags: "text" });

该索引将在后台创建。MongoDB 将解析内容,移除常见的停用词(如 ‘a’, ‘the’, ‘is’),并将单词词干提取到其词根形式。

要使用索引进行搜索,您可以使用 $text 操作符和 $search。

此查询查找所有包含单词 ‘mongodb’ 或 ‘powerful’ 的帖子。

// 搜索包含 'mongodb' 或 'powerful' 的帖子
db.posts.find({ $text: { $search: "mongodb powerful" } });

要搜索精确短语,请将其用双引号括起来。

// 搜索精确短语 "powerful tool"
db.posts.find({ $text: { $search: '"powerful tool"' } });

您可以通过在其前面加上连字符 - 来排除包含特定单词的结果。

// 搜索 'database' 但不包含 'nosql'
db.posts.find({ $text: { $search: "database -nosql" } });

文本搜索的一个关键特性是能够按相关性对结果进行排序。您可以使用 $meta: "textScore" 访问相关性分数并按其排序。

// 查找关于 'mongodb' 的帖子并按相关性排序
db.posts.find(
{ $text: { $search: "mongodb" } },
{ score: { $meta: "textScore" } } // 将分数投影到 'score' 字段中
).sort(
{ score: { $meta: "textScore" } } // 按计算出的文本分数排序
);

此查询将返回最匹配 ‘mongodb’ 的文档,并将其置于结果集的顶部。

如果您不再需要该索引,可以按其名称删除它。首先,使用 getIndexes() 查找索引名称。

> db.posts.getIndexes()
// 文本索引名称通常是 fieldName_text,例如 'content_text'
> db.posts.dropIndex("content_text")
{
"nIndexesWas": 2,
"ok": 1
}