Textabfragen verwenden

Mit den Textsuchfunktionen in Firestore mit MongoDB-Kompatibilität können Sie in einer Sammlung nach bestimmten Strings suchen.

Hinweis

Bevor Sie Textabfragen verwenden, führen Sie folgende Schritte aus:

  1. Prüfen Sie, ob Sie Zugriff auf eine vorhandene MongoDB-kompatible Datenbank für Vorgänge haben , oder erstellen Sie eine Datenbank und stellen Sie eine Verbindung zu ihr her.

  2. Prüfen Sie, ob Sie einen Textindex haben, oder erstellen Sie einen Textindex.

IAM-Berechtigungen

Wenn Sie einen Index in Firestore mit MongoDB-Kompatibilität erstellen möchten, muss Ihnen eine der folgenden Rollen zugewiesen sein:

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

Informationen zum Zuweisen einer Rolle finden Sie unter Einzelne Rolle zuweisen. Weitere Informationen zu Firestore-Rollen und den zugehörigen Berechtigungen finden Sie unter Vordefinierte Rollen.

Wenn Sie benutzerdefinierte Rollen definiert haben, weisen Sie alle folgenden Berechtigungen zu, um Indizes zu erstellen:

  • datastore.indexes.create
  • datastore.indexes.delete
  • datastore.indexes.get
  • datastore.indexes.list
  • datastore.indexes.update

Textabfrage ausführen

Bei Textabfragen wird der Operator $text in einem Filter verwendet. Geben Sie den abgefragten String im Argument $search an.

Allgemeine Textabfrage ausführen

Führen Sie die folgende Abfrage aus, um eine allgemeine Abfrage auszuführen:

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

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

Wenn Ihr Index partitioniert ist, können Sie nach der Partition filtern, indem Sie sie in einen Gleichheitsfilter mit „und“ in Ihre Abfrage einbeziehen. Wenn Sie beispielsweise eine city-Partition haben, können Sie eine Textabfrage so filtern:

db.myCollection.find( { $and: [
  { $text: { $search: "french bread" } },
  { "city": "Paris" }
] } )

Sie können eine Aggregation auch nach einer Partition filtern. Beispiel:

db.myCollection.aggregate([
 { $match: { $text: { $search: "french bread" } } },
 { "city": "Paris" }
] );

Der Wert Ihrer Partition muss ein String sein. Ihr Partitionsfilter muss mit „und“ mit Ihrer Abfrage verknüpft sein.

Abfragesprache festlegen

Sie können die Abfragesprache mit dem Argument $language festlegen. Beispiel:

  db.cities.find({ $text: { $search: "french bread", $language: "en"} })

Wenn Sie die Abfragesprache nicht festlegen, wird die Sprache des Textindexes verwendet.

Nach einem genauen Begriff suchen

Wenn Sie nach einem genauen Begriff suchen möchten, konfigurieren Sie den Begriff als eine Folge von Wörtern in doppelten Anführungszeichen. Beispiel:

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

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

Nach einer Begriffskombination suchen

Wenn Sie Ihre Abfrage präziser gestalten möchten, geben Sie eine Kette von Begriffen an. Die folgende Abfrage gibt beispielsweise Dokumente zurück, die mit der Kombination best AND french AND ("bread" OR "is")übereinstimmen:

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

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

Begriff ausschließen

Wenn Sie einen Begriff aus einer Abfrage ausschließen möchten, stellen Sie dem Begriff einen Bindestrich voran (-):

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

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

Relevanzwert berechnen

Verwenden Sie den {$meta: "textScore"} Ausdruck, um den Relevanzwert der Dokumente zu berechnen, die mit der Textabfrage übereinstimmen. Wenn Sie die Ergebnisse in absteigender Reihenfolge nach der Punktzahl sortieren möchten, verwenden Sie $meta in einem Sortierausdruck. Beachten Sie die folgenden Beispiele, wobei SCORE_FIELD der Name des Felds ist, in dem der Wert gespeichert wird:

  # 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"} } },
  ]);

Sie können den Textwert auch in Projektionsausdrücken verwenden. Beispiel:

  # 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"} } },
  ]);

Abfrage maximieren

Um die Relevanz der Abfrageergebnisse zu verbessern, erweitert der Operator $text den Suchstring entsprechend der angegebenen Sprache, um Übereinstimmungen für kontextbezogene Synonyme, abgeleitete Formen, korrigierte Rechtschreibung, diakritische Varianten und mehr einzubeziehen.

Beschränkungen

  • Die Operatoren $near und $text können nicht in derselben Abfrage verwendet werden.
  • Pro find- oder aggregation-Abfrage ist nur ein $text-Operator zulässig.
  • Bei Aggregationen muss die Phase $match mit $text die erste Pipelinephase sein.
  • $text kann nur in $and und $or verschachtelt werden.
  • Wenn $text in $or enthalten ist, können die nicht suchbezogenen Disjunkte vorhandene sortierte Indizes verwenden, um die Abfrage zu optimieren. Wenn die anderen Disjunkte nicht indexiert sind, wird die Abfrage auf einem Sammlungs-Scan basieren.
  • $text kann nicht mit Abfragehinweisen verwendet werden.
  • Bei Abfragen mit Textsuche kann nicht nach $natural sortiert werden.