Mit Attributen suchen

Durch die Suche mit Attributen können Sie Ihren Dokumenten Kategoriedaten anhängen. Beim Suchvorgang wird ein Attribut/Wert-Paar verwendet. Das Attribut "Größe" kann beispielsweise die Werte "klein", "mittel" und "groß" haben.

Durch die Verwendung von Attributen bei der Suche können Sie zusammenfassende Informationen abrufen, die Ihnen bei der Verfeinerung einer Abfrage helfen und eine Aufschlüsselung der Ergebnisse in mehreren Schritten ermöglichen.

Dies ist bei Anwendungen wie Shoppingwebsites nützlich, auf denen Sie eine Reihe von Filtern anbieten möchten, damit Kunden die angezeigten Produkte eingrenzen können.

Die aggregierten Daten für ein Attribut geben Auskunft über die Verteilung seiner Werte. Das Attribut „Größe” kann beispielsweise in zahlreichen Dokumenten Ihrer Ergebnisse auftauchen. Die aggregierten Daten für dieses Attribut können etwa Auskunft darüber geben, dass der Wert „klein” 100-mal, der Wert „mittel” 300-mal und der Wert „groß” 250-mal vorkommt. Jedes Attribut/Wert-Paar stellt eine Teilmenge von Dokumenten im Abfrageergebnis dar. Jedem Paar ist ein Schlüssel zugeordnet, der als Suchfilter bezeichnet wird. Sie können Suchfilter in eine Abfrage aufnehmen, um Dokumente abzurufen, die mit dem Abfragestring übereinstimmen und deren Attributwerte einem oder mehreren Suchfiltern entsprechen.

Bei einer Suche können Sie wählen, welche Attribute erfasst und in den Ergebnissen angezeigt werden sollen. Sie haben auch die Möglichkeit, die Attributerkennung zu aktivieren, sodass automatisch die am häufigsten in Ihren Dokumenten vorkommenden Attribute ausgewählt werden.

Einem Dokument Attribute hinzufügen

Weisen Sie einem Dokument Attribute zu, bevor Sie es einem Index hinzufügen. Sie sollten dies dann tun, wenn Sie die Felder des Dokuments angeben:

package app

import (
    "appengine"
    "appengine/search"
    "net/http"
)

type ComputerDoc struct {
    Name      search.Atom
    Type      search.Atom `search:",facet"`
    RAMSizeGB float64     `search:",facet"`
}

func handlePut(w http.ResponseWriter, r *http.Request) {
    c := appengine.NewContext(r)
    index, err := search.Open("products")
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    _, err = index.Put(c, "doc1", &ComputerDoc{
        Name:      "x86",
        Type:      "computer",
        RAMSizeGB: 8.0,
    })
    // Handle err and write HTTP response.
}

Ein Attribut ähnelt einem Dokumentfeld, es hat einen Namen und einen Wert.

Attribute werden nach denselben Regeln wie Dokumentfelder benannt: Es wird zwischen Groß- und Kleinschreibung unterschieden und sie dürfen nur ASCII-Zeichen enthalten. Sie müssen mit einem Buchstaben beginnen und können Buchstaben, Ziffern oder Unterstriche enthalten. Ein Name darf maximal 500 Zeichen lang sein.

Der Wert eines Attributs kann entweder ein atomarer String (maximal 500 Zeichen lang) oder eine Zahl (Gleitkommawert mit doppelter Genauigkeit zwischen -2.147.483.647 und 2.147.483.647) sein.

Sie können einem Attribut in einem Dokument mehrere Werte zuweisen. Fügen Sie zu diesem Zweck das Attribut mit demselben Namen und Typ mehrmals hinzu und verwenden Sie dabei jedes Mal einen anderen Wert.

Ein Attribut kann eine unbegrenzte Anzahl von Werten haben. Auch die Anzahl der Attribute, die Sie einem Dokument hinzufügen können, oder die Anzahl der Attribute mit eindeutigen Namen in einem Index ist unbegrenzt.

Beachten Sie, dass ein Attribut bei jeder Verwendung entweder einen atomaren oder einen numerischen Wert annehmen kann. Ein Attribut namens „Größe” kann an ein Dokument mit dem Stringwert „klein” und an ein anderes Dokument mit dem numerischen Wert „8” angehängt werden. Dasselbe Attribut kann sogar mit beiden Werttypen mehrmals in demselben Dokument auftauchen. Es wird jedoch davon abgeraten, für ein Attribut sowohl atomare als auch numerische Werte zu verwenden.

Obgleich ein Attribut, das Sie einem Dokument hinzufügen, einen bestimmten Typ hat, werden in den Suchergebnissen alle Werte des Attributs zusammengefasst. Zum Beispiel könnten die Ergebnisse für das Attribut „Größe” zeigen, dass es 100 Instanzen des Werts „klein”, 150 Instanzen des Werts „mittel” und 135 Instanzen von numerischen Werten im Bereich [4, 8) gab. Die genauen numerischen Werte und die Häufigkeit ihrer Verteilung werden nicht angezeigt.

Wenn Sie ein Dokument mithilfe einer Abfrage abrufen, können Sie nicht direkt auf seine Attribute und Werte zugreifen. Sie müssen angeben, dass mit Ihrer Abfrage Attributinformationen zurückgegeben werden. Dies wird im nächsten Abschnitt erläutert.

Attributinformationen mit einer Attributsuche abrufen

Sie können angeben, dass das Backend für die Suche die am häufigsten verwendeten Attribute für Sie ermitteln soll. Dies wird als „automatische Attributerkennung” bezeichnet. Sie können Attributinformationen auch explizit abrufen, indem Sie ein Attribut nach Name oder nach Name und Wert auswählen. Sie können alle drei Arten des Attributabrufs in einer einzigen Abfrage mischen und abgleichen.

Die Abfrage von Attributinformationen hat keinen Einfluss darauf, welche Dokumente durch die Abfrage zurückgegeben werden. Sie kann jedoch die Leistung beeinträchtigen. Sie erzielen durch eine Suche mit Attributen mit der Standardtiefe 1.000 denselben Effekt, wie wenn Sie als Scorer-Limit für Sortieroptionen 1.000 festlegen.

Automatische Attributerkennung

Bei der automatischen Attributerkennung werden die Attribute gesucht, die in der Zusammenfassung Ihrer Dokumente am häufigsten angezeigt werden. Angenommen, die zu Ihrer Abfrage passenden Dokumente enthalten das Attribut „Farbe”, das fünfmal mit dem Wert „rot”, fünfmal mit dem Wert „weiß” und fünfmal mit dem Wert „blau” vorkommt. Dieses Attribut kommt insgesamt 15-mal vor. Für die Erkennung würde es höher eingestuft werden als das Attribut „Farbton”, das in denselben übereinstimmenden Dokumenten sechsmal mit dem Wert „dunkel” und siebenmal mit dem Wert „hell” auftaucht.

Sie müssen die Attributerkennung aktivieren, indem Sie sie in Ihrer Abfrage festlegen:

func handleSearch(w http.ResponseWriter, r *http.Request) {
    index, err := search.Open("products")
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    it := index.Search(c, "name:x86", &search.SearchOptions{
        Facets: {
            search.AutoFacetDiscovery(0, 0),
        },
    })
    facets, err := it.Facets()
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    for _, results := range facets {
        for i, facet := range result {
            // The facet results are grouped by facet name.
            // Print the name of each group before its values.
            if i == 0 {
                fmt.Fprintf(w, "Facet %s:\n", facet.Name)
            }
            fmt.Fprintf(w, "    %v: count=%d", facet.Value, facet.Count)
        }
    }
}

Wenn Sie Attribute durch Erkennung abrufen, werden standardmäßig nur die zehn am häufigsten vorkommenden Werte eines Attributs zurückgegeben. Dieses Limit kann auf bis zu 100 erhöht werden. Verwenden Sie hierfür den ersten Parameter für AutoFacetDiscovery.

Beachten Sie, dass die automatische Attributerkennung nicht alle möglichen Attribute und deren Werte zurückgeben soll. Welche Attribute durch Erkennung zurückgegeben werden, kann von Ausführung zu Ausführung variieren. Wenn Sie nach bestimmten Attributen suchen möchten, verwenden Sie in der Abfrage den Parameter return_facets.

Stringwerte werden einzeln zurückgegeben. Die numerischen Werte eines erkannten Attributs werden innerhalb eines einzelnen Bereichs [min max) zurückgegeben. Sie können diesen Bereich überprüfen und für eine spätere Abfrage einen kleineren Teilbereich erstellen.

Attribute nach Name auswählen

Um Informationen zu einem Attribut nur nach dessen Name abzurufen, fügen Sie den Suchoptionen Ihrer Abfrage eine FacetDiscovery mit dem Namen des Attributs hinzu:

it := index.Search(c, "name:x86", &search.SearchOptions{
    Facets: {
        FacetDiscovery("Type"),
        FacetDiscovery("RAMSizeGB"),
    },
})

Wenn Sie Attribute nach Name abrufen, werden nur die 10 am häufigsten vorkommenden Werte für ein Attribut zurückgegeben.

Attribute nach Name und Wert auswählen

Um nur Informationen zu bestimmten Werten eines Attributs abzurufen, fügen Sie FacetDiscovery sowohl mit dem Namen des Attributs als auch den gewünschten Werten hinzu:

it := index.Search(c, "name:x86", &search.SearchOptions{
    Facets: {
        // Fetch the "Type" facet with Values "computer" and "printer"
        FacetDiscovery("Type",
            search.Atom("computer"),
            search.Atom("printer"),
        ),
        // Fetch the "RAMSizeGB" facet with values in the ranges [0, 4), [4, 8), and [8, max]
        FacetDiscovery("RAMSizeGB",
            search.Range{Start: 0, End: 4},
            search.Range{Start: 4, End: 8},
            search.AtLeast(8),
        ),
    },
})

Die Werte in einer einzelnen FacetDiscovery müssen alle vom gleichen Typ sein, entweder eine Liste mit search.Atom-Werten oder, bei Zahlen, eine Liste von search.Range-Werten. Dies sind Intervalle, die links (am Anfang) geschlossen sind und rechts (am Ende) offen. Wenn das Attribut sowohl String- als auch Zahlenwerte enthält, fügen Sie jeweils separate FacetDisovery-Objekte hinzu.

Optionen

Sie können die Mindestanzahl von Dokumenten, die zum Erfassen von Attributinformationen ausgewertet werden sollen, festlegen. Nehmen Sie dafür die Option FacetDocumentDepth in die SearchOptions Ihrer Abfrage auf. Wenn sie nicht angegeben ist, liegt diese Tiefe standardmäßig bei 1.000.

Beachten Sie, dass die Attributtiefe normalerweise viel größer als das Abfragelimit ist. Die Attributergebnisse werden mindestens bis zur Tiefe der Dokumente berechnet. Wenn Sie für die Sortieroptionen ein höheres Scoring-Limit als die Tiefe festgelegt haben, wird stattdessen das Scoring-Limit verwendet.

Attributergebnisse abrufen

Wenn Sie in einer Abfrage Attributsuchparameter verwenden, enthalten die aggregierten Attributinformationen auch das Abfrageergebnis selbst.

Der Such-Iterator verfügt über die Methode Facets, die die aggregierten Attributinformationen als [][]FacetResult zurückgibt. Die Ergebnisse sind so aufgebaut, dass für jedes Attribut, das in einem mit Ihrer Abfrage übereinstimmenden Dokument vorkommt, ein Ausschnitt der Attributergebnisse angezeigt wird. Für jedes Ergebnis erhalten Sie

  • den Attributnamen,
  • einen Wert für das Attribut aus der Liste der häufigsten Werte und
  • eine ungefähre Anzahl, wie oft dieser Wert angezeigt wurde.

Beachten Sie, dass die Werteliste den String und die numerischen Werte eines Attributs enthält. Bei automatischer Erkennung des Attributs werden dessen numerische Werte als ein Intervall [min max) zurückgegeben. Wenn Sie explizit ein numerisches Attribut mit einem oder mehreren Bereichen abgefragt haben, enthält die Liste für jeden Bereich ein am Anfang geschlossenes und am Ende offenes Intervall [Anfang Ende).

Die Liste der Attributwerte enthält möglicherweise nicht alle in Ihren Dokumenten gefundenen Werte, da die Abfrageoptionen bestimmen, wie viele Dokumente untersucht und wie viele Werte zurückgegeben werden.

Die aggregierten Informationen für jedes Attribut können aus dem Iterator gelesen werden:

it := index.Search(...)
facets, err := it.Facets()  // And check err != nil.
for _, results := range facets {
    for _, facet := range results {
        ...
    }
}

Beispielsweise könnte eine Abfrage Dokumente gefunden haben, die ein Attribut „Größe” mit den Stringwerten und numerischen Werten enthalten. Die Ergebnisse für dieses Attribut sind folgendermaßen aufgebaut:

[][]search.FacetResult{
    {
        {Name: "size", Value: search.Range{Start: 8, End: 10}, Count: 22},
        {Name: "size", Value: search.Atom("small"), Count: 100},
        {Name: "size", Value: search.Atom("medium"), Count: 300},
        {Name: "size", Value: search.Atom("large"), Count: 250},
    },
}

Mit Attributen Abfragen verfeinern/filtern

Jedes FacetResult kann verwendet werden, um die Ergebnisse weiter zu verfeinern, sodass nur Dokumente mit diesen Attributwerten enthalten sind. Um Abfragen mit einem oder mehreren dieser Schlüssel zu verfeinern, übergeben Sie sie als Suchoptionen:

it := index.Search(c, "...", &search.SearchOptions{
    Refinements: []search.Facet{
        facetResult1.Facet,
        facetResult2.Facet,
    },
})

Sie können Suchfilter für eine oder mehrere unterschiedliche Attribute in derselben Anfrage kombinieren. Alle Suchfilter, die zu demselben Attribut gehören, werden mit einem OR verknüpft. Suchfilter für unterschiedliche Attribute werden mit AND verknüpft.

Es ist auch möglich, ein benutzerdefiniertes Attribut (Facet) zur Verwendung als Suchfilter zu erstellen. Weitere Informationen finden Sie in der Referenz.