テキスト検索を使用する

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 演算子は、同じクエリで使用できません。
  • find または aggregation クエリごとに 1 つの $text 演算子が許可されます。
  • 集計では、$text を含む $match ステージは最初のパイプライン ステージである必要があります。
  • $text$and$or の内部でのみネストできます。
  • $text$or の内側にある場合、検索以外の選言は既存の順序付きインデックスを使用してクエリを最適化できます。他の論理積がインデックスに登録されていない場合、クエリはコレクション スキャンに依存します。
  • $text はクエリヒントでは使用できません。
  • テキスト検索を含むクエリでは、$natural で並べ替えできません。