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. Informationen zum Inhalt des Pakets search finden Sie in der search-Paketreferenz.

Überblick

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
  • Zeitfeld: ein time.Time-Wert, der mit einer Genauigkeit von einer Millisekunde gespeichert wird
  • 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. Nutzer mit der Rolle App Engine-Administrator können über die Seite App Engine Search der Google Cloud Console eine Anfrage senden, um die Größe 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:

index.Search(ctx, "rose water", nil)

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:

index.Search(ctx, "1776-07-04", nil)

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:

// search for documents with pianos that cost less than $5000
index.Search(ctx, "Product = piano AND Price < 5000", nil)

Abfrageoptionen sind, wie der Name schon sagt, 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.

Wir empfehlen das Logging von Abfragestrings in Ihrer Anwendung, wenn Sie eine Liste der ausgeführten Abfragen speichern möchten.

Suchergebnisse

Ein Search-Aufruf gibt einen Iterator-Wert zurück, mit dem der vollständige Satz übereinstimmender Dokumente zurückgegeben werden kann.

Zusätzliches Schulungsmaterial

Zusätzlich zu dieser Dokumentation können Sie den zweiteiligen Kurs zur Search API in der Google Developer's Academy lesen. In dem Kurs wird zwar die Python API verwendet, die weiterführende Erläuterung der Suchkonzepte kann aber trotzdem sehr hilfreich sein.

Dokumente und Felder

Dokumente werden von Go-Strukturen dargestellt, die eine Liste von Feldern enthalten. Sie können auch durch alle anderen Typen dargestellt werden, in denen die Schnittstelle FieldLoadSaver implementiert ist.

Dokument-ID

Jedes Dokument in einem Index muss eine eindeutige Dokument-ID oder docID 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 docID. Sie können die docID auch selbst angeben, während Sie ein Dokument erstellen. Eine docID 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 docID 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 docID 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
  • Zeitfeld: ein time.Time-Wert, der mit einer Genauigkeit von einer Millisekunde gespeichert wird
  • Geopunktfeld: ein Punkt auf der Erde, der durch Breiten- und Längengrade beschrieben wird

Die Stringfeldtypen sind der Go-interne Typ string und HTML des Pakets search und Atom-Typen. Zahlenfelder werden mit dem Go-internen Typ float64 dargestellt. Zeitfelder verwenden den Typ time.Time und "geopoint"-Felder den Typ GeoPoint des Pakets appengine.

Spezielle Behandlung von String- und Zeitfeldern

Wenn einem Index ein Dokument mit Zeit-, Text- oder HTML-Feldern hinzugefügt wird, tritt eine spezielle Behandlung auf. Es hilft zu verstehen, was im Hintergrund passiert, um die Search API effektiv zu 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.

Zeitfeldgenauigkeit

Wenn Sie ein Zeitfeld in einem Dokument erstellen, legen Sie dessen Wert auf time.Time fest. Wenn ein Zeitfeld 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 Zeitfeld zwar einen genauen Zeitwert enthalten kann, bei einer Datumsabfrage aber nur ein Zeitfeldwert im Format yyyy-mm-dd angegeben wird. Es bedeutet auch, dass die Sortierreihenfolge von Datumsfeldern mit demselben Datum nicht klar definiert ist. Der Typ time.Time stellt die Zeit zwar mit einer Genauigkeit im Nanosekundenbereich dar, doch speichert die Search API die Zeit nur mit einer Genauigkeit im Millisekundenbereich.

Andere Dokumentproperties

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. Weitere Informationen zum Festlegen des Rangs finden Sie in der Referenz zu DocumentMetadata.

Das Attribut "Language" der Struktur Field gibt die Sprache an, in der das Feld codiert ist.

Dokument mit anderen Ressourcen verknüpfen

Sie können die docID 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 docID oder als Wert eines Atomfeldes den BlobKey der Daten an.

Dokument erstellen

Das folgende Codebeispiel zeigt, wie ein Dokumentobjekt erstellt wird. Der Typ User gibt die Dokumentstruktur an und ein User-Wert wird auf die übliche Weise erstellt.

import (
	"fmt"
	"net/http"
	"time"

	"golang.org/x/net/context"

	"google.golang.org/appengine"
	"google.golang.org/appengine/search"
)

type User struct {
	Name      string
	Comment   search.HTML
	Visits    float64
	LastVisit time.Time
	Birthday  time.Time
}

func putHandler(w http.ResponseWriter, r *http.Request) {
	id := "PA6-5000"
	user := &User{
		Name:      "Joe Jackson",
		Comment:   "this is <em>marked up</em> text",
		Visits:    7,
		LastVisit: time.Now(),
		Birthday:  time.Date(1960, time.June, 19, 0, 0, 0, 0, nil),
	}
	// ...

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 docID indexiert.

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

// ...
ctx := appengine.NewContext(r)
index, err := search.Open("users")
if err != nil {
	http.Error(w, err.Error(), http.StatusInternalServerError)
	return
}
_, err = index.Put(ctx, id, user)
if err != nil {
	http.Error(w, err.Error(), http.StatusInternalServerError)
	return
}
fmt.Fprint(w, "OK")

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

Die Put-Methode gibt eine docID zurück. Wenn Sie die docID nicht selbst angegeben haben, können Sie das Ergebnis prüfen, um die generierte docID zu ermitteln:

id, err = index.Put(ctx, "", user)
if err != nil {
	http.Error(w, err.Error(), http.StatusInternalServerError)
	return
}
fmt.Fprint(w, id)

Beachten Sie, dass durch das Erstellen einer Instanz der Klasse Index 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.

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 docID ersetzen.

Dokumente nach docID abrufen

Verwenden Sie die Methode Index.Get, um ein Dokument aus einem Index anhand seiner docID abzurufen:

func getHandler(w http.ResponseWriter, r *http.Request) {
	ctx := appengine.NewContext(r)

	index, err := search.Open("users")
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	id := "PA6-5000"
	var user User
	if err := index.Get(ctx, id, &user); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	fmt.Fprint(w, "Retrieved document: ", user)
}

Dokumente anhand ihres Inhalts suchen

Sie können Dokumente aus einem Index abrufen, indem Sie einen Abfragestring erstellen und Index.Search aufrufen. SearchSearch gibt einen Iterator zurück, der übereinstimmende Dokumente in absteigender Rangfolge liefert.

func searchHandler(w http.ResponseWriter, r *http.Request) {
	ctx := appengine.NewContext(r)

	index, err := search.Open("myIndex")
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	for t := index.Search(ctx, "Product: piano AND Price < 5000", nil); ; {
		var doc Doc
		id, err := t.Next(&doc)
		if err == search.Done {
			break
		}
		if err != nil {
			fmt.Fprintf(w, "Search error: %v\n", err)
			break
		}
		fmt.Fprintf(w, "%s -> %#v\n", id, doc)
	}
}

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.

Sie können Dokumente aus einem Index löschen, wenn Sie die docID des entsprechenden Dokuments für die Methode Index.Delete angeben.

func deleteHandler(w http.ResponseWriter, r *http.Request) {
	ctx := appengine.NewContext(r)

	index, err := search.Open("users")
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	id := "PA6-5000"
	err = index.Delete(ctx, id)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	fmt.Fprint(w, "Deleted document: ", id)
}

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 liefern kann, die nicht die neuesten Änderungen enthalten.

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.

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 Google Cloud 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:
    • Index.Get: 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”.