翻译或纠错本页面

在聚合管道中使用文本搜索

2.6 新版功能.

在聚合管道中,可以通过 $text 操作符在 $match 阶段使用文本搜索。

限制

Text search in the aggregation pipeline has the following restrictions:

  • 包含了 $text$match 阶段必须是管道中的 第一个 阶段。

  • 操作符 $text 只能在阶段中出现一次。

  • 操作符 $text 不能出现在 $or$not 表达式中。

  • 默认地,文本搜索不会返回按照匹配得分的顺序返回匹配文档。可以选择在 $sort 阶段使用 $meta 聚合表达式。

文本得分

操作符 $text 会对在被索引的键上含有搜索词的每个文档打分。该得分显示了该文档和给定文本搜索查询的相关性。该得分可以是 $sort pipeline 管道中明细的一部分也可以用于映射(projection)。表达式 { $meta: "textScore" } 可以提供 $text 查询的操作过程的相关信息。参见 $meta aggregation 了解更多在排序和映射中访问文本得分的细节。

元数据(metadata) 只有在包含了 $text 操作的 $match 阶段才是可用的。

例子

下例中,假设在集合 articlessubject 键上有一个文本索引:

db.articles.createIndex( { subject: "text" } )

计算包含某个词的文章的总浏览量

如下操作在 $match 阶段聚合搜索单词 cake 并在 $group 阶段计算匹配文档的 views 之和。

db.articles.aggregate(
   [
     { $match: { $text: { $search: "cake" } } },
     { $group: { _id: null, views: { $sum: "$views" } } }
   ]
)

返回以文本搜索得分排序后的结果

如果需要根据文本搜索得分排序,可以在 $sort 阶段包含 $meta 表达式。以下例子中,查询匹配单词 caketea 的文档,并以 textScore` 降序进行排序,最后在结果集中只返回 title

db.articles.aggregate(
   [
     { $match: { $text: { $search: "cake tea" } } },
     { $sort: { score: { $meta: "textScore" } } },
     { $project: { title: 1, _id: 0 } }
   ]
)

元数据决定了排序的顺序。例如,这里的元数据 "textScore" 按降序进行排序。参见 $meta 了解更多元数据的信息,以及查看一个覆盖元数据的默认排序顺序的例子。

匹配文本得分

元数据 "textScore" 可以用于排序,映射和 $match 阶段之后的条件,这里的 $match 阶段必须包含 $text 操作。

下例中,查询匹配单词 cake tea 的文档,映射 titlescore 键,然后只返回那些 score 值大于 1.0 的文档。

db.articles.aggregate(
   [
     { $match: { $text: { $search: "cake tea" } } },
     { $project: { title: 1, _id: 0, score: { $meta: "textScore" } } },
     { $match: { score: { $gt: 1.0 } } }
   ]
)