1.概要
MongoDB支持对字符串内容执行文本搜索的查询操作。要执行文本搜索,MongoDB使用文本索引和$text操作符。
提示:视图不支持文本搜索。
2.例子
这个例子演示了如何构建一个文本索引并使用它来查找咖啡店,只给出文本字段。
使用以下文件创建集合存储:
db.stores.insert(
[
{ _id: 1, name: "Java Hut", description: "Coffee and cakes" },
{ _id: 2, name: "Burger Buns", description: "Gourmet hamburgers" },
{ _id: 3, name: "Coffee Shop", description: "Just coffee" },
{ _id: 4, name: "Clothes Clothes Clothes", description: "Discount clothing" },
{ _id: 5, name: "Java Shopping", description: "Indonesian goods" }
]
)
2.1 文本索引
MongoDB提供文本索引来支持对字符串内容的文本搜索查询。文本索引可以包含值为字符串或字符串元素数组的任何字段。
要执行文本搜索查询,必须在集合上有一个文本索引。一个集合只能有一个文本搜索索引,但该索引可以覆盖多个字段。
例如,您可以在mongo shell中运行以下命令,以允许对名称和描述字段进行文本搜索:
db.stores.createIndex( { name: "text", description: "text" } )
2.2 $text操作
使用$text查询操作符对具有文本索引的集合执行文本搜索。
$text将使用空白和大多数标点符号作为分隔符标记搜索字符串,并在搜索字符串中执行逻辑或所有此类标记。
例如,您可以使用以下查询来查找包含“coffee”、“shop”和“java”列表中的任何术语的所有商店:
db.stores.find( { $text: { $search: "java coffee shop" } } )
2.3 精确检索
你也可以通过双引号来搜索准确的短语。如果$search字符串包含短语和单个术语,则文本搜索将仅匹配包含短语的文档。
例如,下面会找到所有包含“coffee shop”的文档:
db.stores.find( { $text: { $search: "\"coffee shop\"" } } )
2.4 排序
默认情况下,MongoDB将以未排序的顺序返回结果。但是,文本搜索查询将为每个文档计算一个相关分数,该分数指定文档与查询的匹配程度。
要对结果排序的相关性得分,你必须明确项目的$meta textScore字段和排序:
db.stores.find(
{ $text: { $search: "java coffee shop" } },
{ score: { $meta: "textScore" } }
).sort( { score: { $meta: "textScore" } } )
在聚合管道中也可以使用文本搜索。
3. 语言支持
MongoDB支持各种语言的文本搜索。有关受支持语言的列表,请参阅文本搜索语言。
4.文本索引
MongoDB提供文本索引来支持对字符串内容的文本搜索查询。文本索引可以包含值为字符串或字符串元素数组的任何字段。
要执行文本搜索查询,必须在集合上有一个文本索引。一个集合只能有一个文本搜索索引,但该索引可以覆盖多个字段。
例如,您可以在mongo shell中运行以下命令,以允许对名称和描述字段进行文本搜索:
db.stores.createIndex( { name: "text", description: "text" } )
5. 文本检索操作
- 查询框架
- 聚合框架
提示:视图不支持文本搜索。
5.1 查询框架
使用$text查询操作符对具有文本索引的集合执行文本搜索。
$text将使用空白和大多数标点符号作为分隔符标记搜索字符串,并在搜索字符串中执行逻辑或所有此类标记。
:例如,您可以使用以下查询来查找包含“coffee”、“shop”和“java”列表中的任何术语的所有商店:
db.stores.find( { $text: { $search: "java coffee shop" } } )
使用$meta查询操作符根据每个匹配文档的相关性得分获取和排序。例如,要按相关顺序订购咖啡店列表,请运行以下命令:
db.stores.find(
{ $text: { $search: "coffee shop cake" } },
{ score: { $meta: "textScore" } }
).sort( { score: { $meta: "textScore" } } )
5.2 聚合框架
在使用聚合框架时,使用$match和$text表达式来执行文本搜索查询。要按相关性得分对结果排序,请使用$sort阶段[1]中的$meta聚合操作符。
$meta投影操作符的行为和要求与$meta聚合操作符不同。有关$meta聚合操作符的详细信息,请参阅$meta聚合操作符参考页面。
6. 聚合管道中的文本搜索
在聚合管道中,可以通过在$match阶段使用$text查询操作符来进行文本搜索。
6.1 限制条件
有关通用$text操作符限制,请参阅操作符限制。
此外,聚合管道中的文本搜索有以下限制:
- 包含$text的$match阶段必须是管道中的第一个阶段。
- 文本操作符在舞台中只能出现一次。
- 文本操作符表达式不能出现在$or或$not表达式中。
- 默认情况下,文本搜索不按照匹配分数的顺序返回匹配的文档。在$sort阶段使用$元聚合表达式。
6.2 Text Score
$text操作符为索引字段中包含搜索项的每个文档赋值。分数表示文档与给定文本搜索查询的相关性。分数可以是$sort管道规范的一部分,也可以是投影表达式的一部分。表达式提供了处理$text操作的信息。有关为投影或排序访问分数的详细信息,请参见$meta聚合。
元数据仅在包含$text操作的$match阶段之后可用。
6.2.1例子
下面的例子假设一个集合文章有一个字段主题的文本索引:
db.articles.createIndex( { subject: "text" } )
6.3 计算包含单词的文章的总视图
下面的聚合将在$match阶段搜索术语cake,并计算$group阶段中匹配文档的总视图。
db.articles.aggregate(
[
{ $match: { $text: { $search: "cake" } } },
{ $group: { _id: null, views: { $sum: "$views" } } }
]
)
6.4 返回按文本搜索得分排序的结果
要根据文本搜索得分进行排序,请在$sort阶段中包含一个$meta表达式。下面的示例匹配术语cake或tea,按textScore降序排序,只返回结果集中的title字段。
db.articles.aggregate(
[
{ $match: { $text: { $search: "cake tea" } } },
{ $sort: { score: { $meta: "textScore" } } },
{ $project: { title: 1, _id: 0 } }
]
)
指定的元数据确定排序顺序。例如,“textScore”元数据按降序排序。有关元数据的更多信息,以及覆盖元数据默认排序顺序的示例,请参见$meta。
6.5 Match on Text Score
“textScore”元数据可用于包括$text操作的$match阶段之后的投影、排序和条件。
下面的示例匹配术语cake或tea,投射标题和得分字段,然后只返回得分大于1.0的文档。
db.articles.aggregate(
[
{ $match: { $text: { $search: "cake tea" } } },
{ $project: { title: 1, _id: 0, score: { $meta: "textScore" } } },
{ $match: { score: { $gt: 1.0 } } }
]
)
6.6 为文本搜索指定一种语言
以下聚合搜索在$match阶段中包含术语saber但不包含术语claro的文档,并计算$group阶段中匹配文档的总视图。
db.articles.aggregate(
[
{ $match: { $text: { $search: "saber -claro", $language: "es" } } },
{ $group: { _id: null, views: { $sum: "$views" } } }
]
)
7.文本搜索语言
文本索引和$text操作符可与下列语言一起使用,并接受由两个字母组成的ISO 639-1语言代码或语言名称的长形式:
| Language Name | ISO 639-1 (Two letter codes) |
|---|---|
danish | da |
dutch | nl |
english | en |
finnish | fi |
french | fr |
german | de |
hungarian | hu |
italian | it |
norwegian | nb |
portuguese | pt |
romanian | ro |
russian | ru |
spanish | es |
swedish | sv |
turkish | tr |
提示:如果您指定的语言值为“none”,那么文本搜索使用简单的标记化,没有停止词列表,也没有词干提取。
3494

被折叠的 条评论
为什么被折叠?



