使用文本查询
使用与 MongoDB 兼容的 Firestore 中的文本搜索功能,在集合中搜索特定字符串。
准备工作
在使用文本查询之前,请执行以下操作:
确保您有权访问现有的与 MongoDB 兼容的操作 数据库,或者 创建数据库并连接到该数据库。
确保您有文本索引,或者 创建文本索引。
IAM 权限
如需在与 MongoDB 兼容的 Firestore 中创建索引,请确保您分配有以下任一角色:
roles/datastore.ownerroles/datastore.indexAdminroles/editorroles/owner
如需授予角色,请参阅授予单个角色。如需详细了解 Firestore 角色及关联权限,请参阅 预定义角色。
如果您定义了自定义角色,则必须为其分配以下所有权限才能创建索引:
datastore.indexes.createdatastore.indexes.deletedatastore.indexes.getdatastore.indexes.listdatastore.indexes.update
运行文本查询
文本查询在过滤条件中使用 $text 运算符。在 $search 实参中指定查询的字符串。
运行一般文本查询
运行以下查询以执行一般查询:
# Find query
db.cities.find({ $text: { $search: "french bread" } })
# Aggregation query
db.cities.aggregate([
{ $match: { $text: { $search: "french bread" } } }
]);
如果您的索引已分区,则可以在查询中添加“and”等式过滤条件,以按分区进行过滤。
例如,如果您有 city 分区,则可以按如下方式过滤文本查询:
db.myCollection.find( { $and: [
{ $text: { $search: "french bread" } },
{ "city": "Paris" }
] } )
您还可以根据分区过滤聚合。例如:
db.myCollection.aggregate([
{ $match: { $text: { $search: "french bread" } } },
{ "city": "Paris" }
] );
分区的值必须是字符串。分区过滤条件必须使用“and”与查询联接。
设置查询语言
您可以使用 $language 实参设置查询语言。例如:
db.cities.find({ $text: { $search: "french bread", $language: "en"} })
如果您未设置查询语言,则查询会使用文本索引的语言。
查询确切的术语
如需查询确切的术语,请将该术语配置为用英文双引号括起来的字词序列。例如:
# Find query
db.cities.find({ $text: { $search: "\"best french bread\"" } })
# Aggregation query
db.cities.aggregate([
{ $match: { $text: { $search: "\"best french bread\"" } } },
]);
查询术语组合
如需使查询更精确,请指定一系列术语。例如,以下查询会返回与 best AND french AND ("bread" OR "is")组合匹配的文档:
# Find query
db.cities.find({ $text: { $search: "\"best\" \"french\" bread is" } })
# Aggregation query
db.cities.aggregate([
{ $match: { $text: { $search: "\"best\" \"french\" bread is" } } },
]);
排除术语
如需从查询中排除术语,请在该术语前加上连字符 (-):
# Find query
db.cities.find({ $text: { $search: "best bread -french"} })
# Aggregation query
db.cities.aggregate([
{ $match: { $text: { $search: "best bread -french" } } },
]);
计算相关性得分
使用 {$meta: "textScore"} 表达式计算相关性得分
文本查询匹配的文档。如需按得分降序对结果进行排序,请在排序表达式中使用 $meta。请考虑以下示例,
其中 SCORE_FIELD 是用于存储得分
值的字段的名称:
# Find query
db.cities
.find({ $text: { $search: "best french bread" } })
.sort({ SCORE_FIELD: { $meta: "textScore" } })
# Aggregation query
db.cities.aggregate([
{ $match: { $text: { $search: "best french bread" } } },
{ $sort: { "SCORE_FIELD": { $meta: "textScore"} } },
]);
您还可以在投影表达式中使用文本得分。例如:
# Find query
db.cities
.find({ $text: { $search: "best french bread" } })
.project({ score: { $meta: "textScore" } })
# Aggregation query
db.cities.aggregate([
{ $match: { $text: { $search: "best french bread" } } },
{ $project: { "scoreField": { $meta: "textScore"} } },
]);
展开查询
为了提高查询结果的相关性,$text 运算符会根据指定的语言扩充搜索字符串,以包含上下文感知同义词、词干形式、拼写更正后的术语、变音符号变体等的匹配项。
限制
$near运算符和$text运算符不能在同一查询中使用。- 每个
find或aggregation查询中只允许使用一个$text运算符。 - 在聚合中,带有
$text的$match阶段必须是第一个流水线阶段。 $text只能嵌套在$and和$or中。- 如果
$text位于$or中,则非搜索析取项可以使用现有的有序索引来优化查询。如果其他析取项未编入索引,则查询将依赖于集合扫描。 $text不能与查询提示一起使用。- 使用文本搜索的查询无法按
$natural排序。