本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
使用 Amazon DocumentDB 执行文本搜索
Amazon DocumentDB 的原生全文搜索功能允许您使用特殊用途的文本索引对大型文本数据集执行文本搜索。本节介绍文本索引功能的功能,并提供有关如何在 Amazon DocumentDB 中创建和使用文本索引的步骤。还列出了文本搜索限制。
支持的功能
亚马逊 DocumentDB 文本搜索支持以下与 MongoDB API 兼容的功能:
在单个字段上创建文本索引。
创建包含多个文本字段的复合文本索引。
执行单词或多字搜索。
使用权重控制搜索结果。
按分数对搜索结果进行排序。
在聚合管道中使用文本索引。
搜索确切的短语。
使用亚马逊 DocumentDB 文本索引
要在包含字符串数据的字段上创建文本索引,请指定字符串 “text”,如下所示:
单字段索引:
db.test.createIndex({"comments": "text"})
此索引支持在指定集合的 “comments” 字符串字段中进行文本搜索查询。
在多个字符串字段上创建复合文本索引:
db.test.createIndex({"comments": "text", "title":"text"})
此索引支持在指定集合中的 “注释” 和 “标题” 字符串字段中进行文本搜索查询。创建复合文本索引时,您最多可以指定 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”)的字符串 “apple” 或 “apple” 的所有文档:
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"}}]})
输出:
上面的命令返回的文档的文本索引字段包含任何形式的 “兴趣”,“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”,或者其他格式(例如 “apple”)的 “apple”,并根据文档与搜索词的相关程度对结果进行排序。此命令的输出如下所示:
{ "_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 }
$text
$search
,还支持aggregate
、count
、findAndModify
update
、和delete
命令。
聚合运算符
聚合管道使用 $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”: [“apple”, “pie”]} 在 “a” 上创建文本索引将失败。
不支持通配符文本索引。
不支持唯一的文本索引。
不支持排除某个术语。
最佳做法和指南
为了在涉及按文本分数排序的文本搜索查询中获得最佳性能,我们建议您在加载数据之前创建文本索引。
文本索引需要额外的存储空间来优化索引数据的内部副本。这会产生额外的成本影响。
限制
在 Amazon DocumentDB 中,文本搜索存在以下限制:
仅基于亚马逊 DocumentDB 5.0 实例的集群支持文本搜索。