Search API für gebündelte Legacy-Dienste

Die Search API bietet ein Modell für die Indexierung von Dokumenten, die strukturierte Daten enthalten. Sie können damit einen Index durchsuchen sowie Suchergebnisse organisieren und präsentieren. Die API unterstützt den Volltextabgleich für Stringfelder. Dokumente und Indexe werden in einem separaten nichtflüchtigen Speicher abgelegt, der für Suchvorgänge optimiert wurde. Die Search API kann eine beliebige Anzahl von Dokumenten indexieren, für Anwendungen, die sehr große Ergebnismengen abrufen, ist jedoch unter Umständen der App Engine Datastore besser geeignet.

Übersicht

Die Search API basiert auf vier Hauptkonzepten: Dokumente, Indexe, Abfragen und Ergebnisse.

Dokumente

Ein Dokument ist ein Objekt mit einer eindeutigen ID und einer Liste von Feldern, die Nutzerdaten enthalten. Jedes Feld enthält einen Namen und einen Typ. Es gibt verschiedene Feldtypen, die durch die Arten von Werten identifiziert werden, die sie enthalten:

  • Atomfeld: Ein unteilbarer Zeichenstring
  • Textfeld: Ein einfacher Textstring, der Wort für Wort durchsucht werden kann
  • HTML-Feld: Ein String, der HTML-Markup-Tags enthält; nur Text außerhalb der Markup-Tags kann durchsucht werden
  • Zahlenfeld: Eine Gleitkommazahl
  • Datumsfeld – ein Datumsobjekt mit Jahr/Monat/Tag und optionaler Uhrzeit
  • Geopunktfeld – ein Datenobjekt mit Längen- und Breitengraden

Die maximale Größe eines Dokuments beträgt 1 MB.

Indexe

Ein Index speichert Dokumente zum Abrufen. Sie können ein einzelnes Dokument anhand seiner ID, eine Reihe von Dokumenten mit fortlaufenden IDs oder alle Dokumente in einem Index abrufen. Außerdem können Sie einen Index durchsuchen, um Dokumente abzurufen, die bestimmte Kriterien für Felder und die zugehörigen Werte erfüllen. Diese Kriterien werden als Abfragestring angegeben. Gruppen von Dokumenten können Sie verwalten, indem Sie sie in separate Indexe einfügen.

Die Anzahl der Dokumente in einem Index sowie die Anzahl der Indexe, die Sie verwenden können, unterliegen keiner Beschränkung. Die Gesamtgröße aller Dokumente in einem einzelnen Index ist standardmäßig auf 10 GB beschränkt. Sie können jedoch über die Seite App Engine Search in der Google Cloud Console eine Anfrage senden, um die Begrenzung auf bis zu 200 GB zu erhöhen.

Abfragen

Erstellen Sie eine Abfrage, die einen Abfragestring und gegebenenfalls einige zusätzliche Optionen enthält, um einen Index zu durchsuchen. Ein Abfragestring gibt Bedingungen für die Werte eines oder mehrerer Dokumentfelder an. Wenn Sie einen Index durchsuchen, werden nur die darin enthaltenen Dokumente ausgegeben, deren Felder die Abfragekriterien erfüllen.

Bei der einfachsten Abfrage, die manchmal als „globale Suche” bezeichnet wird, handelt es sich um einen String, der nur Feldwerte enthält. Die folgende Suche verwendet einen String, der nach Dokumenten sucht, die die Wörter "rose" und "water" enthalten:

def simple_search(index):
    index.search('rose water')

Der folgende String ist für eine Suche nach Dokumenten mit Datumsfeldern, die das Datum 4. Juli 1776 enthalten, oder mit Textfeldern, die den String "1776-07-04" enthalten:

def search_date(index):
    index.search('1776-07-04')

Ein Abfragestring kann auch spezifischer sein. Er kann einen oder mehrere Begriffe enthalten, die jeweils ein Feld und eine Einschränkung für den Feldwert benennen. Die genaue Form eines Begriffs hängt vom Feldtyp ab. Angenommen, es gibt ein Textfeld mit dem Namen "Product" und ein Zahlenfeld mit dem Namen "Price". Hier ein Abfragestring mit zwei Begriffen:

def search_terms(index):
    # search for documents with pianos that cost less than $5000
    index.search("product = piano AND price < 5000")

Abfrageoptionen sind nicht erforderlich. Sie ermöglichen aber eine Vielzahl von Funktionen:

  • Die Anzahl der Dokumente, die als Suchergebnisse zurückgegeben werden, kann festgelegt werden.
  • Dokumentfelder, die in den Ergebnissen berücksichtigt werden sollen, können angegeben werden. Standardmäßig werden alle Felder aus dem Originaldokument berücksichtigt. Sie können aber auch angeben, dass die Ergebnisse nur eine Teilmenge von Feldern enthalten sollen. Das Originaldokument wird hierbei nicht verändert.
  • Ergebnisse können sortiert werden.
  • „Berechnete Felder“ für Dokumente mit FieldExpressions und gekürzten Textfeldern können mithilfe von Snippets erstellt werden.
  • Das Durchblättern von Suchergebnissen kann unterstützt werden. Dazu wird mithilfe von Offsets und Cursors jeweils nur ein Teil der mit einer Abfrage übereinstimmenden Dokumente zurückgegeben.

Suchergebnisse

Ein Aufruf von search() kann nur eine begrenzte Anzahl von übereinstimmenden Dokumenten zurückgeben. Bei der Suche werden möglicherweise viel mehr Dokumente gefunden, als in einem einzigen Aufruf zurückgegeben werden können. Bei jedem Suchaufruf wird eine Instanz der Klasse SearchResults zurückgegeben. Diese Klasse enthält Informationen dazu, wie viele Dokumente gefunden und wie viele zurückgegeben wurden. Außerdem wird eine Liste der zurückgegebenen Dokumente ausgegeben. Sie können dieselbe Suche mit Cursors oder Offsets wiederholen, um alle übereinstimmenden Dokumente abzurufen.

Zusätzliches Schulungsmaterial

Zusätzlich zu dieser Dokumentation können Sie die zweiteilige Schulung zur Search API in der Google Developer's Academy lesen. Die Schulung enthält eine Beispielanwendung in Python.

Dokumente und Felder

Die Klasse Document stellt Dokumente dar. Jedes Dokument hat eine Dokument-ID und eine Liste von Feldern.

Dokument-ID

Jedes Dokument in einem Index muss eine eindeutige Dokument-ID oder doc_id haben. Die ID kann verwendet werden, um ein Dokument aus einem Index abzurufen, ohne eine Suche durchzuführen. Standardmäßig generiert die Search API bei der Erstellung eines Dokuments automatisch eine doc_id. Sie können die doc_id auch selbst angeben, während Sie ein Dokument erstellen. Eine doc_id darf nur sichtbare, druckbare ASCII-Zeichen (ASCII-Codes 33 bis einschließlich 126) enthalten und darf nicht länger als 500 Zeichen sein. Eine Dokument-ID darf nicht mit einem Ausrufezeichen („!”) beginnen und nicht mit doppelten Unterstrichen („__”) beginnen und enden.

Es ist zwar praktisch, lesbare, aussagekräftige eindeutige Dokument-IDs zu erstellen, Sie können die doc_id jedoch nicht in eine Suche einschließen. Stellen Sie sich das folgende Szenario vor: Sie haben einen Index mit Dokumenten, die Teile darstellen, wobei die Seriennummer des Teils als doc_id verwendet wird. Dadurch lässt sich das Dokument für ein einzelnes Teil mühelos abzurufen, aber es ist unmöglich, nach einer Reihe von Seriennummern zusammen mit anderen Feldwerten, wie z. B. dem Kaufdatum, zu suchen. Wenn die Seriennummer in einem Atomfeld gespeichert ist, stellt dies kein Problem mehr dar.

Dokumentfelder

Ein Dokument enthält Felder mit einem Namen, einem Typ und einem einzelnen Wert dieses Typs. Zwei oder mehr Felder können denselben Namen, aber unterschiedliche Typen haben. Zum Beispiel können Sie zwei Felder mit dem Namen „Alter” definieren: eines mit einem Texttyp (Wert „Zweiundzwanzig”), das andere mit einem Zahlentyp (Wert 22).

Feldnamen

Feldnamen berücksichtigen die Groß- und Kleinschreibung und dürfen nur ASCII-Zeichen enthalten. Sie müssen mit einem Buchstaben beginnen und können Buchstaben, Ziffern oder Unterstriche enthalten. Ein Feldname darf nicht länger als 500 Zeichen sein.

Mehrwertige Felder

Ein Feld darf nur einen einzigen Wert enthalten, der dem Feldtyp entsprechen muss. Feldnamen müssen nicht eindeutig sein. Ein Dokument kann mehrere Felder mit demselben Namen und demselben Typ haben, wodurch ein Feld mit mehreren Werten dargestellt werden kann. Datums- und Zahlenfelder mit demselben Namen dürfen jedoch nicht wiederholt werden. Ein Dokument kann auch mehrere Felder mit demselben Namen und unterschiedlichen Feldtypen enthalten.

Feldtypen

Es gibt drei Arten von Feldern, die Zeichenketten speichern. Diese werden als Stringfelder bezeichnet:

  • Textfeld: ein String mit einer maximalen Länge von 1.024**2 Zeichen
  • HTML-Feld: ein HTML-formatierter String mit einer maximalen Länge von 1.024**2 Zeichen
  • Atomfeld: ein String mit einer maximalen Länge von 500 Zeichen

Außerdem gibt es drei Feldtypen, die nicht textbasierte Daten speichern:

  • Zahlenfeld: Ein Gleitkommawert mit doppelter Genauigkeit zwischen -2.147.483.647 und 2.147.483.647
  • Datumsfeld: Ein datetime.date oder datetime.datetime.
  • Geopunktfeld: ein Punkt auf der Erde, der durch Breiten- und Längengrade beschrieben wird

Die Feldtypen werden über die Klassen TextField, HtmlField, AtomField, NumberField, DateField und GeoField festgelegt.

Spezielle Behandlung von String- und Datumsfeldern

Wenn ein Dokument mit Datums-, Text- oder HTML-Feldern einem Index hinzugefügt wird, erfordert dies eine spezielle Behandlung. Wenn Sie verstehen, was im Hintergrund passiert, können Sie die Search API effektiver nutzen.

Tokenisierung von Stringfeldern

Wenn ein HTML- oder Textfeld indexiert wird, wird sein Inhalt in Tokens aufgeteilt, also tokenisiert. Der String wird überall dort aufgeteilt, wo er Leerzeichen oder Sonderzeichen (Interpunktionszeichen, Rautezeichen, Backslash usw.) enthält. Der Index enthält für jedes Token einen Eintrag. Auf diese Weise können Sie nach Suchbegriffen und Wortgruppen suchen, die nur einen Teil des Feldwerts umfassen. Zum Beispiel liefert die Suche nach „dark” ein Dokument mit einem Textfeld, das den String „it was a dark and stormy night” enthält. Bei der Suche nach „time” wird ein Dokument mit einem Textfeld ausgegeben, das den String „this is a real-time system” enthält.

In HTML-Feldern wird Text innerhalb von Markup-Tags nicht tokenisiert. Ein Dokument mit einem HTML-Feld, das it was a <strong>dark</strong> night enthält, wird bei einer Suche nach „night“ zurückgegeben, aber nicht bei einer Suche nach „strong“. Möchten Sie die Suche nach Markup-Text ermöglichen, speichern Sie diesen in einem Textfeld.

Atomfelder werden nicht tokenisiert. Ein Dokument mit einem Atomfeld mit dem Wert „schlechtes Wetter” wird nur bei einer Suche nach dem gesamten String „schlechtes Wetter” zurückgegeben. Es stimmt nicht mit einer Suche nach „schlechtes” oder „Wetter” überein.

Regeln für die Tokenisierung
  • Der Unterstrich (_) sowie das kaufmännische Und-Zeichen (&) unterteilen Wörter nicht in Tokens.

  • Die folgenden Leerraumzeichen unterteilen Wörter immer in Tokens: Leerzeichen, Zeilenumbruch, Zeilenvorschub, horizontaler Tabulator, vertikaler Tabulator, Seitenvorschub und NULL.

  • Die folgenden Zeichen werden als Interpunktion behandelt und unterteilen Wörter in Tokens:

    !"%()
    *,-|/
    []]^`
    :=>?@
    {}~$
  • Die Zeichen in der folgenden Tabelle unterteilen Wörter normalerweise in Tokens, aber sie werden je nach dem Kontext, in dem sie angezeigt werden, unterschiedlich behandelt:

    Zeichen Regel
    < In einem HTML-Feld zeigt das „Kleiner als”-Zeichen den Beginn eines HTML-Tags an, das ignoriert wird.
    + Ein String aus einem oder mehreren Pluszeichen wird als Teil des Wortes behandelt, wenn er am Ende des Wortes steht („C++”).
    # Das Rautezeichen wird als Teil des Wortes behandelt, wenn ihm a, b, c, d, e, f, g, j oder x vorangestellt sind (a# bis g# sind Musiknoten; j# und x# sind Programmiersprachen, c# ist beides). Steht „#” vor einem Begriff („#google”), wird es als Hashtag behandelt und somit als Teil des Wortes.
    ' Ein Apostroph gilt als Buchstabe, wenn es dem Buchstaben „s” vorangeht, gefolgt von einem Wortumbruch, z. B. im Englischen „John's hat”.
    . Wenn ein Punkt zwischen Ziffern steht, ist dieser Teil einer Zahl (z. B. das Tausendertrennzeichen oder der englische Dezimalpunkt). Er kann auch Teil eines Wortes sein, wenn er in einem Akronym verwendet wird (A.B.C).
    - Der Bindestrich ist Teil eines Wortes, wenn er in einem Akronym verwendet wird (I-B-M).
  • Alle anderen 7-Bit-Zeichen außer Buchstaben und Ziffern („A-Z”, „a-z”, „0-9”) werden als Interpunktion behandelt und unterteilen Wörter in Tokens.

  • Alles andere wird als UTF-8-Zeichen geparst.

Akronyme

Bei der Aufteilung in Tokens werden spezielle Regeln zur Erkennung von Akronymen (Strings wie „I.B.M.”, „a-b-c” oder „C I A”) angewandt. Ein Akronym ist ein String aus einzelnen Buchstaben mit demselben Trennzeichen zwischen allen Zeichen. Gültige Trennzeichen sind Punkte, Bindestriche oder eine beliebige Anzahl von Leerzeichen. Die Trennzeichen werden bei der Tokenisierung aus dem String entfernt. Daher werden die oben erwähnten Beispielstrings zu den Tokens „ibm”, „abc” und „cia”. Der ursprüngliche Text im Dokumentfeld wird dabei nicht verändert.

Beachten Sie beim Umgang mit Akronymen Folgendes:

  • Ein Akronym darf nicht mehr als 21 Buchstaben enthalten. Ein gültiger Akronymstring mit mehr als 21 Buchstaben wird in eine Folge von Akronymen mit jeweils 21 Buchstaben oder weniger unterteilt.
  • Wenn die Buchstaben in einem Akronym durch Leerzeichen getrennt sind, müssen alle Buchstaben einheitlich groß- oder kleingeschrieben sein. In Akronymen, die mit Punkt oder Bindestrich geschrieben werden, können Sie Groß- und Kleinbuchstaben gemischt verwenden.
  • Wenn Sie nach einem Akronym suchen, können Sie die kanonische Form des Akronyms eingeben (also den String ohne Trennzeichen) oder das Akronym mit Bindestrich oder Punkt (nicht aber mit beidem) als Trennzeichen zwischen den Buchstaben. So könnte der Text „I.B.M” mit jedem der Suchbegriffe „I-B-M”, „I.B.M” oder „IBM” abgerufen werden.

Datumsfeldgenauigkeit

Wenn Sie ein Datumsfeld in einem Dokument erstellen, legen Sie dessen Wert auf ein datetime.date oder datetime.datetime fest. In Python können nur "naive" Datums- und Uhrzeitobjekte verwendet werden. "Bewusste" Objekte sind nicht zulässig. . Wenn ein Datumsfeld indexiert bzw. darin gesucht wird, werden Zeitkomponenten ignoriert und das Datum in die Anzahl der Tage seit dem 1.1.1970 UTC umgerechnet. Das bedeutet, dass ein Datumsfeld zwar einen genauen Uhrzeitwert enthalten kann, bei einer Datumsabfrage aber nur ein Datumsfeldwert im Format yyyy-mm-dd angegeben wird. Es bedeutet auch, dass die sortierte Reihenfolge von Datumsfeldern mit demselben Datum nicht klar definiert ist.

Andere Dokumentattribute

Der Rang eines Dokuments ist eine positive Ganzzahl, mit der die Standardreihenfolge von Dokumenten bestimmt wird, die eine Suche zurückgibt. Standardmäßig wird der Rang bei der Dokumenterstellung auf die Anzahl der Sekunden seit dem 01. Januar 2011 festgelegt. Sie können beim Erstellen eines Dokuments den Rang explizit festlegen. Es ist nicht ratsam, vielen Dokumenten denselben Rang zuzuweisen, und Sie sollten niemals mehr als 10.000 Dokumenten den gleichen Rang erteilen. Wenn Sie Sortieroptionen angeben, können Sie den Rang als Sortierschlüssel verwenden. Ein Rang wird als _rank referenziert, wenn er in einem Sortierausdruck oder einem Feldausdruck verwendet wird.

Das Attribut "language" gibt die Sprache an, in der die Felder codiert sind.

Weitere Informationen zu diesen Attributen finden Sie auf der Referenzseite zur Klasse Document.

Dokument mit anderen Ressourcen verknüpfen

Sie können die doc_id und andere Felder eines Dokuments als Links zu anderen Ressourcen in Ihrer Anwendung verwenden. Wenn Sie beispielsweise Blobstore nutzen, können Sie das Dokument mit einem bestimmten Blob verknüpfen. Dazu geben Sie als doc_id oder als Wert eines Atomfeldes den BlobKey der Daten an.

Dokument erstellen

Das folgende Codebeispiel zeigt, wie ein Dokumentobjekt erstellt wird. Der Konstruktor "Document" wird mit dem Argument "fields" aufgerufen, das auf eine Liste von Feldobjekten festgelegt ist. Mit der Konstruktorfunktion der Feldklasse wird jedes Objekt in der Liste erstellt und initialisiert. Beachten Sie die Verwendung des Konstruktors GeoPoint und der Python-Klasse datetime, um die entsprechenden Typen von Feldwerten zu erstellen.

def create_document():
    document = search.Document(
        # Setting the doc_id is optional. If omitted, the search service will
        # create an identifier.
        doc_id='PA6-5000',
        fields=[
            search.TextField(name='customer', value='Joe Jackson'),
            search.HtmlField(
                name='comment', value='this is <em>marked up</em> text'),
            search.NumberField(name='number_of_visits', value=7),
            search.DateField(name='last_visit', value=datetime.now()),
            search.DateField(
                name='birthday', value=datetime(year=1960, month=6, day=19)),
            search.GeoField(
                name='home_location', value=search.GeoPoint(37.619, -122.37))
        ])
    return document

Mit einem Index arbeiten

Dokumente in einen Index einfügen

Wenn Sie ein Dokument in einen Index einfügen, wird das Dokument in den nichtflüchtigen Speicher kopiert und alle darin enthaltenen Felder werden nach Name, Typ und doc_id indexiert.

Das folgende Codebeispiel zeigt, wie Sie auf einen Index zugreifen und ein Dokument einfügen können:

def add_document_to_index(document):
    index = search.Index('products')
    index.put(document)
Sie können bis zu 200 Dokumente gleichzeitig an die Methode put() übergeben. Es ist effizienter, die Methode „put” für mehrere Dokumente gleichzeitig anstatt für einzelne Dokumente auszuführen.

Wenn Sie ein Dokument in einen Index einfügen und der Index bereits ein Dokument mit derselben doc_id enthält, ersetzt das neue Dokument das alte. Es wird keine Warnung ausgegeben. Sie können Index.get(id) aufrufen, bevor Sie ein Dokument erstellen oder in einen Index aufnehmen. Dadurch können Sie prüfen, ob eine bestimmte doc_id bereits vorhanden ist.

Die Methode put gibt eine Liste von PutResults zurück, eines für jedes als Argument übergebene Dokument. Wenn Sie die doc_id nicht selbst angegeben haben, können Sie das Attribut id des Ergebnisses prüfen, um die generierte doc_id zu ermitteln:

def add_document_and_get_doc_id(documents):
    index = search.Index('products')
    results = index.put(documents)
    document_ids = [document.id for document in results]
    return document_ids

Beachten Sie, dass durch das Erstellen einer Instanz der Index-Klasse nicht garantiert wird, dass tatsächlich ein nichtflüchtiger Index vorhanden ist. Ein nichtflüchtiger Index wird erst erstellt, wenn Sie ihm mit der Methode put zum ersten Mal ein Dokument hinzufügen. Mit der Methode search.get_indexes() können Sie prüfen, ob ein Index vorhanden ist, bevor Sie ihn verwenden.

Dokumente aktualisieren

Ein Dokument kann nicht geändert werden, nachdem Sie es einem Index hinzugefügt haben. Sie können weder Felder einfügen oder entfernen noch den Wert eines Feldes ändern. Sie können das Dokument jedoch durch ein neues Dokument mit der gleichen doc_id ersetzen.

Dokumente nach doc_id abrufen

Es gibt zwei Möglichkeiten, Dokumente über die Dokument-ID aus einem Index abzurufen:
  • Verwenden Sie Index.get() zum Abrufen eines einzelnen Dokuments anhand seiner doc_id.
  • Mit Index.get_range() können Sie eine Gruppe von aufeinanderfolgenden Dokumenten abrufen, die nach doc_id sortiert sind.

Beide Aufrufe werden im folgenden Beispiel dargestellt.

def get_document_by_id():
    index = search.Index('products')

    # Get a single document by ID.
    document = index.get("AZ125")

    # Get a range of documents starting with a given ID.
    documents = index.get_range(start_id="AZ125", limit=100)

    return document, documents

Dokumente anhand ihres Inhalts suchen

Sie können Dokumente aus einem Index abrufen, indem Sie einen Abfragestring erstellen und Index.search() aufrufen. Der Abfragestring kann direkt als Argument übergeben oder in ein Abfrageobjekt aufgenommen werden, das als Argument übergeben wird. Standardmäßig werden übereinstimmende Dokumente von search() in absteigender Rangfolge zurückgegeben. Wenn Sie steuern möchten, wie viele Dokumente in welcher Reihenfolge geliefert werden, oder wenn den Ergebnissen berechnete Felder hinzugefügt werden sollen, müssen Sie das Query-Objekt verwenden, das einen Abfragestring enthält und mit dem außerdem weitere Such- und Sortieroptionen angegeben werden können.

def query_index():
    index = search.Index('products')
    query_string = 'product: piano AND price < 5000'

    results = index.search(query_string)

    for scored_document in results:
        print(scored_document)

Index löschen

Jeder Index besteht aus indexierten Dokumenten und einem Indexschema. Sie löschen einen Index, indem Sie alle Dokumente in einem Index und anschließend das Indexschema löschen.

Wenn Sie einzelne Dokumente aus einem Index löschen möchten, geben Sie in der Methode index.delete() die doc_id von mindestens einem zu löschenden Dokument an. Es ist effizienter, mehrere Dokumente gebündelt zu löschen. Sie können bis zu 200 Dokument-IDs gleichzeitig an die Methode delete() übergeben.

def delete_index(index):
    # index.get_range by returns up to 100 documents at a time, so we must
    # loop until we've deleted all items.
    while True:
        # Use ids_only to get the list of document IDs in the index without
        # the overhead of getting the entire document.
        document_ids = [
            document.doc_id
            for document
            in index.get_range(ids_only=True)]

        # If no IDs were returned, we've deleted everything.
        if not document_ids:
            break

        # Delete the documents for the given IDs
        index.delete(document_ids)

    # delete the index schema
    index.delete_schema()
Sie können bis zu 200 Dokumente gleichzeitig an die Methode delete() übergeben. Es ist effizienter, Löschvorgänge für mehrere Dokumente gleichzeitig statt einzeln auszuführen.

Eventual Consistency

Wenn Sie ein Dokument in einen Index einfügen oder ein Dokument in einem Index aktualisieren oder löschen, wird die Änderung über mehrere Rechenzentren hinweg übernommen. Dies geschieht normalerweise schnell, die Dauer kann jedoch variieren. Die Search API garantiert Eventual Consistency. Das heißt, dass in manchen Fällen eine Suche oder das Abrufen eines oder mehrerer Dokumente Ergebnisse zurückgeben kann, die nicht den neuesten Änderungen entsprechen.

Größe eines Index ermitteln

Ein Index speichert Dokumente zum Abrufen. Sie können ein einzelnes Dokument anhand seiner ID, eine Reihe von Dokumenten mit fortlaufenden IDs oder alle Dokumente in einem Index abrufen. Außerdem können Sie einen Index durchsuchen, um Dokumente abzurufen, die bestimmte Kriterien für Felder und die zugehörigen Werte erfüllen. Diese Kriterien werden als Abfragestring angegeben. Sie können Gruppen von Dokumenten verwalten, indem Sie sie in separate Indexe einfügen. Die Anzahl der Dokumente in einem Index oder die Anzahl der Indexe, die Sie verwenden können, unterliegt keiner Beschränkung. Die Gesamtgröße aller Dokumente in einem einzelnen Index ist standardmäßig auf 10 GB beschränkt. Sie können jedoch über die Seite App Engine Search in der Google Cloud Console eine Anfrage senden, die Begrenzung auf bis zu 200 GB zu erhöhen. Das Indexattribut storage_limit ist die maximal zulässige Größe eines Index.

Das Indexattribut storage_usage stellt eine Schätzung des Speicherplatzes dar, der von einem Index belegt wird. Diese Zahl ist eine Schätzung, da das Indexüberwachungssystem nicht ständig ausgeführt wird. Die tatsächliche Nutzung wird regelmäßig berechnet. Die storage_usage wird zwischen den Probenpunkten angepasst. Dabei werden hinzugefügte Dokumente berücksichtigt, Löschungen jedoch nicht.

Asynchrone Vorgänge ausführen

Sie können asynchrone Aufrufe verwenden, um mehrere Vorgänge ohne Blockierung auszuführen. Am Ende werden alle Ergebnisse gleichzeitig abgerufen und nur einmal blockiert. Der folgende Code führt beispielsweise mehrere Suchvorgänge asynchron aus:

def async_query(index):
    futures = [index.search_async('foo'), index.search_async('bar')]
    results = [future.get_result() for future in futures]
    return results

Indexschemas

Jeder Index verfügt über ein Schema, das alle Feldnamen und Feldtypen anzeigt, die in den enthaltenen Dokumenten vorkommen. Sie können Schemas nicht selbst definieren. Schemas werden dynamisch verwaltet. Sie werden aktualisiert, wenn einem Index Dokumente hinzugefügt werden. Hier ist ein Beispiel für ein einfaches Schema in JSON-ähnlicher Form:

{'comment': ['TEXT'], 'date': ['DATE'], 'author': ['TEXT'], 'count': ['NUMBER']}

Jeder Schlüssel im Wörterbuch ist der Name eines Dokumentfeldes. Der Wert des Schlüssels ist eine Liste der Feldtypen, die mit diesem Feldnamen verwendet werden. Wenn Sie denselben Feldnamen mit unterschiedlichen Feldtypen verwendet haben, listet das Schema mehrere Feldtypen für einen Feldnamen auf:

{'ambiguous-integer': ['TEXT', 'NUMBER', 'ATOM']}

Sobald ein Feld in einem Schema angezeigt wird, kann es nicht mehr entfernt werden. Ein Feld kann nicht mehr gelöscht werden, selbst wenn der Index keine Dokumente mehr mit diesem speziellen Feldnamen enthält.

Sie können die Schemas für Ihre Indexe auf folgende Weise ansehen:

from google.appengine.api import search
...
for index in search.get_indexes(fetch_schema=True):
    logging.info("index %s", index.name)
    logging.info("schema: %s", index.schema)
Beim Aufrufen von get_indexes können nicht mehr als 1.000 Indexe zurückgegeben werden. Rufen Sie die Funktion wiederholt mit dem Argument start_index_name auf, um weitere Indexe abzurufen.

Ein Schema definiert keine "Klasse" im Sinne der Objektprogrammierung. Für die Search API ist jedes Dokument einmalig und Indexe können verschiedene Arten von Dokumenten enthalten. Wenn Sie Sammlungen von Objekten mit derselben Liste von Feldern als Instanzen einer Klasse behandeln möchten, müssen Sie dies in Ihrem Code erzwingen. Sie können beispielsweise festlegen, dass alle Dokumente mit demselben Satz an Feldern in einem eigenen Index geführt werden. Das Indexschema könnte dabei als Klassendefinition angesehen werden und jedes Dokument im Index wäre dann eine Instanz der Klasse.

Indexe in der Google Cloud Console anzeigen

In der Console können Sie Informationen zu den Indexen Ihrer Anwendung und den darin enthaltenen Dokumenten einsehen. Durch Klicken auf einen Indexnamen werden die Dokumente angezeigt, die der Index enthält. Es werden alle definierten Schemafelder für den Index angezeigt. Für jedes Dokument mit einem Feld dieses Namens sehen Sie den Wert des Feldes. Sie können die Indexdaten auch direkt über die Console abfragen.

Kontingente für die Search API

Die Search API hat mehrere kostenlose Kontingente:

Ressourcen- oder API-Aufruf Kostenloses Kontingent
Gesamtspeicherplatz (Dokumente und Indexe) 0,25 GB
Abfragen 1.000 Abfragen pro Tag
Dokumente zu Indexen hinzufügen 0,01 GB pro Tag

Die folgenden Grenzwerte werden von der Search API festgelegt, um einen zuverlässigen Dienst zu gewährleisten. Sie gelten für kostenlose und kostenpflichtige Anwendungen:

Ressource Sicherheitskontingent
Maximale Abfrageverwendung 100 aggregierte Minuten Abfrageausführungszeit pro Minute
Maximale Anzahl von hinzugefügten oder gelöschten Dokumenten 15.000 pro Minute
Maximale Größe pro Index (eine unbegrenzte Anzahl von Indexen ist erlaubt) 10 GB

Die API-Nutzung wird je nach Art des Aufrufs unterschiedlich gezählt:

  • Index.search(): Jeder API-Aufruf zählt als eine Abfrage. Die Ausführungszeit entspricht der Latenz des Aufrufs.
  • Index.put(): Wenn Sie Dokumente zu Indexen hinzufügen, werden die Größe jedes Dokuments und die Anzahl der Dokumente zum Indexierungskontingent hinzugerechnet.
  • Alle anderen Search API-Aufrufe werden basierend auf der Anzahl der zugehörigen Vorgänge gezählt:
    • search.get_indexes(): Jede tatsächliche Rückgabe eines Index wird als 1 Vorgang gezählt; ebenso wird es als 1 Vorgang gezählt, wenn nichts zurückgegeben wird.
    • Index.get() und Index.get_range(): Jede tatsächliche Rückgabe eines Dokuments wird als 1 Vorgang gezählt; ebenso wird es als 1 Vorgang gezählt, wenn nichts zurückgegeben wird.
    • Index.delete(): Jedes Dokument in der Anfrage wird als 1 Vorgang gezählt; ebenso wird es als 1 Vorgang gezählt, wenn die Anfrage leer ist.

Das Kontingent für den Abfragedurchsatz ist so festgelegt, dass ein einzelner Nutzer den Suchdienst nicht für sich alleine beanspruchen kann. Da Abfragen gleichzeitig ausgeführt werden können, darf jede Anwendung Abfragen ausführen, die pro Minute Taktzeit bis zu 100 Minuten Ausführungszeit beanspruchen. Wenn Sie viele kurze Abfragen ausführen, werden Sie diesen Grenzwert wahrscheinlich nicht erreichen. Sobald Sie das Kontingent überschritten haben, schlagen nachfolgende Abfragen fehl, bis der nächste Zeitabschnitt beginnt und Ihr Kontingent erneuert wird. Das Kontingent wird nicht streng in einminütigen Abständen durchgesetzt. Es wird eine Variation des Leaky-Bucket-Algorithmus verwendet, um die Suchbandbreite in Fünf-Sekunden-Schritten zu steuern.

Weitere Informationen zu Kontingenten finden Sie auf der Seite „Kontingente”. Wenn eine Anwendung versucht, diese Grenzwerte zu überschreiten, wird durch eine Fehlermeldung auf das unzureichende Kontingent hingewiesen.

Diese Grenzwerte werden zwar pro Minute durchgesetzt, die Konsole zeigt jedoch die Gesamtwerte pro Tag an. Kunden mit der Supportstufe Silber, Gold oder Platin können bei dem für sie zuständigen Supportmitarbeiter höhere Durchsatzlimits anfragen.

Preise für die Search API

Werden bei der Nutzung die kostenlosen Kontingente überschritten, fallen die folgenden Gebühren an:

Ressource Kosten
Gesamtspeicherplatz (Dokumente und Indexe) 0,18 $ pro GB pro Monat
Abfragen 0,50 $ pro 10.000 Abfragen
Indexierung durchsuchbarer Dokumente 2,00 $ pro GB

Weitere Informationen zur Preisgestaltung finden Sie auf der Seite „Preise”.