Docs 菜单

搜索文本

在本指南中,您可以学习;了解如何使用 Mongoid 来运行文本搜索。文本搜索可让您高效地查询具有字符串值的字段。

MongoDB提供文本索引来支持对具有字符串值或值为字符串元素数组的字段进行文本搜索查询。 要学习;了解有关文本索引的更多信息,请参阅服务器手册中的 自管理部署上的文本索引。

注意

Atlas Search

本指南重点介绍文本搜索。 如果您的数据库托管在MongoDB Atlas上,则可以使用Atlas Search功能来执行更强大、更灵活的文本搜索。 要学习;了解有关Atlas Search 的更多信息,请参阅Atlas文档中的Atlas Search概述。

您可以通过执行以下步骤来运行文本搜索:

  1. 在模型上定义文本索引。

  2. 在目标集合上创建文本索引。

  3. 执行文本搜索查询。

以下部分介绍如何执行其中的每项操作。

使用 index 宏在模型定义中指定文本索引。 以下代码创建一个 Dish 模型类,其中包括 description字段上的文本索引:

class Dish
include Mongoid::Document
field :name, type: String
field :description, type: String
index description: 'text'
end

注意

您必须将索引类型指定为字符串,如前面代码中的 'text' 所示。

接下来,您必须在集合中创建文本索引。 您可以使用Atlas 用户界面或Compass等界面创建索引。如果您使用 Rails框架开发应用应用程序,则可以运行以下 Rake任务,根据模型规范创建索引:

bundle exec rake db:mongoid:create_indexes

要学习;了解有关将索引与 Mongoid 结合使用的更多信息,请参阅 使用索引优化查询指南。

要执行文本搜索,请使用 $text 评估查询运算符,然后在查询过滤中使用 $search字段。 $text操作符对文本索引字段执行文本搜索。 $search字段指定要在文本索引字段中搜索的文本。 要学习;了解有关此操作符的更多信息,请参阅服务器手册中的 $text 参考资料。

要搜索一个术语,请在查询筛选器中将此术语指定为一个字符串。要搜索多个术语,请在字符串中使用空格分隔每个术语。

注意

搜索多个术语

搜索多个术语时,Mongoid 返回文本索引字段中至少包含其中一个术语的文档。

假设您使用字符串 'cake coffee cream'搜索。 以下列表描述了与此文本查询匹配的值:

  • 'Has strong coffee notes.'

  • 'Good for creamy coffee fans.'

  • 'A rich but light cake.'

  • 'A creamy coffee cake with cranberries.'

以下示例对包含术语'herb'description 值运行文本搜索:

Dish.where('$text' => {'$search' => 'herb'})
# Sample output
{"_id":"...","description":"A bright, herb-based salad. A perfect starter for vegetarians and vegans.","name":"Kale Tabbouleh"}
{"_id":"...","description":"Grilled whole fish stuffed with herbs and pomegranate seeds. Serves 3-4.","name":"Herbed Whole Branzino"}

提示

尽管搜索术语是'herb' ,但该方法也会匹配包含'herbs' 的描述,因为MongoDB文本索引使用后缀词干来匹配相似单词。要学习;了解有关MongoDB如何匹配术语的更多信息,请参阅 {+server-manual} 中的文本索引属性。

要搜索查询过滤中将带有转义引号的短语指定为字符串。 如果不在短语两边添加转义引号,Mongoid 会运行术语搜索。

提示

转义引号是一个反斜杠字符 (\),后跟一个双引号字符 (")。

以下示例对包含短语 "serves 2"description 值运行文本搜索:

Dish.where('$text' => {'$search' => "\"serves 2\""})
# Sample output
{"_id":"...","description":"A vegetarian take on the classic dish that uses lentils as a base. Serves 2.","name":"Shepherd’s Pie"}
{"_id":"...","description":"Baked trout seasoned with garlic, lemon, dill, and, of course, butter. Serves 2.","name":"Garlic Butter Trout"}

对于要从文本搜索中排除的每个术语或短语,请在查询过滤中指定以减号 (-) 为前缀的术语或短语作为字符串。

重要

您必须至少搜索一个术语才能从搜索中排除词语。 如果您不搜索任何词语,Mongoid 将不会返回任何文档。

以下示例对包含术语'vegan' 但不包含术语'tofu'description 值运行文本搜索:

Dish.where('$text' => {'$search' => 'vegan -tofu'})
# Sample output
{"_id":"...","description":"A bright, herb-based salad. A perfect starter for vegetarians and vegans.","name":"Kale Tabbouleh"}

要学习;了解有关构建查询筛选器的更多信息,请参阅指定文档查询。

要学习;了解有关执行增删改查操作的更多信息,请参阅执行数据操作指南。