使用文字搜尋

使用 Cloud Firestore 的文字搜尋功能,在集合中搜尋特定字串。

事前準備

開始使用文字查詢前,請先完成下列步驟:

  1. 確認您有權存取現有的 MongoDB 相容作業資料庫,或建立資料庫並連線

  2. 確認您有文字索引,或建立文字索引

IAM 權限

如要在 Cloud Firestore 中建立索引,請確認您已獲派下列任一角色:

  • roles/datastore.owner
  • roles/datastore.indexAdmin
  • roles/editor
  • roles/owner

如要授予角色,請參閱「授予單一角色」。如要進一步瞭解 Cloud Firestore 角色和相關聯的權限,請參閱「預先定義角色」。

如果您已定義自訂角色,請指派下列所有權限來建立索引:

  • datastore.indexes.create
  • datastore.indexes.delete
  • datastore.indexes.get
  • datastore.indexes.list
  • datastore.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 運算子無法在同一項查詢中使用。
  • 每個 findaggregation 查詢只能有一個 $text 運算子。
  • 在匯總中,具有 $text$match 階段必須是第一個管道階段。
  • $text 只能巢狀內嵌在 $and$or 中。
  • 如果 $text 位於 $or 內,非搜尋不連通項可能會使用現有的排序索引來最佳化查詢。如果其他不相交的項目未建立索引,查詢就會依賴集合掃描。
  • $text 無法與查詢提示搭配使用。
  • 使用文字搜尋的查詢無法依 $natural 排序。