执行 Amazon DocumentDB 文本搜索 - Amazon DocumentDB

执行 Amazon DocumentDB 文本搜索

借助 Amazon DocumentDB 的原生全文搜索功能,您可以使用特殊用途的文本索引对大型文本数据集执行文本搜索。本节介绍文本索引功能的功能,并提供了有关如何在 Amazon DocumentDB 中创建和使用文本索引的步骤。还列出了文本搜索的限制。

支持的功能

Amazon DocumentDB 文本搜索支持以下 MongoDB API 兼容功能:

  • 在单个字段上创建文本索引。

  • 创建包含多个文本字段的复合文本索引。

  • 执行单字或多字搜索。

  • 使用权重控制搜索结果。

  • 通过打分对搜索结果进行排序。

  • 在聚合管道中使用文本索引。

  • 搜索确切的短语。

要在包含字符串数据的字段上创建文本索引,需指定以下所示的字符串“text”:

单个字段索引:

db.test.createIndex({"comments": "text"})

此索引支持在指定集合的“comments”字符串字段中进行文本搜索查询。

在多个字符串字段上创建复合文本索引:

db.test.createIndex({"comments": "text", "title":"text"})

此索引支持在指定集合中的“comments”和“title”字符串字段中进行文本搜索查询。在创建复合文本索引时,最多可指定 30 个字段。一旦创建后,文本搜索查询将对所有索引字段进行查询。

注意

每个集合只能有一个文本索引。

列出 Amazon DocumentDB 集合上的文本索引

您可以在集合上使用 getIndexes() 来识别和描述文本索引等索引,如下例所示:

rs0:PRIMARY> db.test.getIndexes() [ { "v" : 4, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.test" }, { "v" : 1, "key" : { "_fts" : "text", "_ftsx" : 1 }, "name" : "contents_text", "ns" : "test.test", "default_language" : "english", "weights" : { "comments" : 1 }, "textIndexVersion" : 1 } ]

创建索引后,开始将数据插入 Amazon DocumentDB 集合。

db.test.insertMany([{"_id": 1, "star_rating": 4, "comments": "apple is red"}, {"_id": 2, "star_rating": 5, "comments": "pie is delicious"}, {"_id": 3, "star_rating": 3, "comments": "apples, oranges - healthy fruit"}, {"_id": 4, "star_rating": 2, "comments": "bake the apple pie in the oven"}, {"_id": 5, "star_rating": 5, "comments": "interesting couch"}, {"_id": 6, "star_rating": 5, "comments": "interested in couch for sale, year 2022"}])

运行文本搜索查询

运行单字文本搜索查询

需要使用 $text$search 运算符来执行文本搜索。以下示例返回文本索引字段中包含字符串“apple”或“apples”等其他格式字符串的所有文档:

db.test.find({$text: {$search: "apple"}})

输出:

该命令的输出内容类似如下所示:

{ "_id" : 1, "star_rating" : 4, "comments" : "apple is red" } { "_id" : 3, "star_rating" : 3, "comments" : "apples, oranges - healthy fruit" } { "_id" : 4, "star_rating" : 2, "comments" : "bake the apple pie in the oven" }

运行多字文本搜索

您还可以对 Amazon DocumentDB 数据执行多字文本搜索。以下命令返回文本索引字段中含有“apple”或“pie”的文档:

db.test.find({$text: {$search: "apple pie"}})

输出:

该命令的输出内容类似如下所示:

{ "_id" : 1, "star_rating" : 4, "comments" : "apple is red" } { "_id" : 2, "star_rating" : 5, "comments" : "pie is delicious" } { "_id" : 3, "star_rating" : 3, "comments" : "apples, oranges - healthy fruit" } { "_id" : 4, "star_rating" : 2, "comments" : "bake the apple pie in the oven" }

运行多字短语文本搜索

对于多字短语搜索,请使用以下示例:

db.test.find({$text: {$search: "\"apple pie\""}})

输出:

上述命令返回文本索引字段中含有确切短语“apple pie”的文档:该命令的输出内容类似如下所示:

{ "_id" : 4, "star_rating" : 2, "comments" : "bake the apple pie in the oven" }

使用筛选器进行文本搜索

您还可以将文本搜索与其他查询运算符结合起来使用,按照附加条件筛选结果:

db.test.find({$and: [{star_rating: 5}, {$text: {$search: "interest"}}]})

输出:

上述命令返回文本索引字段中包含任何形式的“interest”且“star_rating”等于 5 的文档。该命令的输出内容类似如下所示:

{ "_id" : 5, "star_rating" : 5, "comments" : "interesting couch" } { "_id" : 6, "star_rating" : 5, "comments" : "interested in couch for sale, year 2022" }

限制文本搜索中返回的文档数量

可以选择使用 limit 限制返回的文档数量:

db.test.find({$and: [{star_rating: 5}, {$text: {$search: "couch"}}]}).limit(1)

输出:

上述命令返回一个满足筛选器的结果:

{ "_id" : 5, "star_rating" : 5, "comments" : "interesting couch" }

通过文本打分对结果进行排序

以下示例通过文本打分对文本搜索结果进行排序:

db.test.find({$text: {$search: "apple"}}, {score: {$meta: "textScore"}}).sort({score: {$meta: "textScore"}})

输出:

上述命令返回文本索引字段中包含“apple”或“apples”等其他格式的文档,并根据文档与搜索词的相关程度对结果进行排序。该命令的输出内容类似如下所示:

{ "_id" : 1, "star_rating" : 4, "comments" : "apple is red", "score" : 0.6079270860936958 } { "_id" : 3, "star_rating" : 3, "comments" : "apples, oranges - healthy fruit", "score" : 0.6079270860936958 } { "_id" : 4, "star_rating" : 2, "comments" : "bake the apple pie in the oven", "score" : 0.6079270860936958 }

aggregatecountfindAndModifyupdatedelete 命令也支持 $text$search

聚合运算符

使用 $match 的聚合管道

db.test.aggregate( [{ $match: { $text: { $search: "apple pie" } } }] )

输出:

上述命令返回以下结果:

{ "_id" : 1, "star_rating" : 4, "comments" : "apple is red" } { "_id" : 3, "star_rating" : 3, "comments" : "apple - a healthy fruit" } { "_id" : 4, "star_rating" : 2, "comments" : "bake the apple pie in the oven" } { "_id" : 2, "star_rating" : 5, "comments" : "pie is delicious" }

其他聚合运算符的组合

db.test.aggregate( [ { $match: { $text: { $search: "apple pie" } } }, { $sort: { score: { $meta: "textScore" } } }, { $project: { score: { $meta: "textScore" } } } ] )

输出:

上述命令返回以下结果:

{ "_id" : 4, "score" : 0.6079270860936958 } { "_id" : 1, "score" : 0.3039635430468479 } { "_id" : 2, "score" : 0.3039635430468479 } { "_id" : 3, "score" : 0.3039635430468479 }

在创建文本索引时指定多个字段

最多可以为复合文本索引中的三个字段分配权重。分配给文本索引中的字段的默认权重为一 (1)。权重为可选参数,须介于 1 到 100000 之间。

db.test.createIndex( { "firstname": "text", "lastname": "text", ... }, { weights: { "firstname": 5, "lastname":10, ... }, name: "name_text_index" } )

与 MongoDB 的差异

Amazon DocumentDB 的文本索引功能使用反向索引和词频算法。文本索引默认为稀疏索引。由于解析逻辑、令牌化分隔符等方面的差异,对于相同的数据集或查询形状,可能无法返回与 MongoDB 相同的结果集。

Amazon DocumentDB 文本索引和 MongoDB 之间还存在以下差异:

  • 不支持采用非文本索引的复合索引。

  • Amazon DocumentDB 文本索引不区分大小写和变音符号。

  • 文本索引仅支持英语。

  • 不支持数组(或多键)字段的文本索引。例如,使用文档对“a”创建文本索引 {“a”:[“apple”, “pie”]} 将会失败。

  • 不支持通配符文本索引。

  • 不支持唯一文本索引。

  • 不支持排除某个词。

最佳实践和准则

  • 为了优化通过文本打分排序进行文本搜索查询的性能,我们建议在加载数据之前创建文本索引。

  • 文本索引需要额外的存储空间来实现索引数据内部副本的最优化。这将产生额外的费用。

限制

Amazon DocumentDB 中的文本搜索存在以下限制:

  • 只有 Amazon DocumentDB 5.0 基于实例的集群支持文本搜索。