使用文字搜索

使用 Cloud Firestore 中的文本搜索功能在集合中搜索特定字符串。

准备工作

在开始使用文本搜索之前,请执行以下操作:

  1. 确保您有权访问现有的 MongoDB 兼容操作数据库,或创建数据库并连接到该数据库。

  2. 确保您有文本索引,或创建文本索引。

文本搜索在过滤条件中使用 $text 运算符。在 $search 参数中指定查询字符串。

运行以下命令以执行常规文本搜索:

  # Find search
  db.cities.find({ $text: { $search: "french bread" } })

  # Aggregation search
  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 search
  db.cities.find({ $text: { $search: "\"best french bread\"" } })

  # Aggregation search
  db.cities.aggregate([
    { $match: { $text: { $search: "\"best french bread\"" } } },
  ]);

搜索字词组合

如需使文本搜索更精确,请指定一连串字词。例如,以下搜索会返回与组合 best AND french AND ("bread" OR "is") 匹配的文档:

  # Find search
  db.cities.find({ $text: { $search: "\"best\" \"french\" bread is" } })

  # Aggregation search
  db.cities.aggregate([
    { $match: { $text: { $search: "\"best\" \"french\" bread is" } } },
  ]);

排除字词

如需从文本搜索中排除某个字词,请在该字词前面加上连字符 (-):

  # Find search
  db.cities.find({ $text: { $search: "best bread -french"} })

  # Aggregation search
  db.cities.aggregate([
    { $match: { $text: { $search: "best bread -french" } } },
  ]);

计算相关性得分

使用 {$meta: "textScore"} 表达式计算文本搜索匹配的文档的相关性得分。如需按得分降序对结果进行排序,请在排序表达式中使用 $meta。请考虑以下示例,其中 SCORE_FIELD 是用于存储分数值的字段的名称:

  # Find search
  db.cities
    .find({ $text: { $search: "best french bread" } })
    .sort({ SCORE_FIELD: { $meta: "textScore" } })

  # Aggregation search
  db.cities.aggregate([
    { $match: { $text: { $search: "best french bread" } } },
    { $sort: { "SCORE_FIELD": { $meta: "textScore"} } },
  ]);

您还可以在投影表达式中使用文本得分。例如:

  # Find search
  db.cities
    .find({ $text: { $search: "best french bread" } })
    .project({ score: { $meta: "textScore" } })

  # Aggregation search
  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 排序。