Umgang mit Suchergebnissen

Wenn ein Abfrageaufruf normal abgeschlossen wird, erfolgt die Rückgabe des Ergebnisses in Form eines SearchResults-Objekts. Das Ergebnisobjekt gibt an, wie viele übereinstimmende Dokumente im Index gefunden und wie viele davon zurückgegeben wurden. Außerdem enthält es eine Liste übereinstimmender ScoredDocuments. Die Liste enthält normalerweise einen Teil aller gefundenen übereinstimmenden Dokumente, da die Suche bei jedem Aufruf eine begrenzte Anzahl von Dokumenten zurückgibt. Mithilfe eines Offsets oder Cursors können Sie alle übereinstimmenden Dokumente abrufen, jeweils in Form einer Teilmenge.

Ergebnisse

def query_results(index, query_string):
    result = index.search(query_string)
    total_matches = result.number_found
    list_of_docs = result.results
    number_of_docs_returned = len(list_of_docs)
    return total_matches, list_of_docs, number_of_docs_returned

Je nach Wert der Abfrageoption limit kann die Anzahl der übereinstimmenden Dokumente, die im Ergebnis zurückgegeben werden, geringer als die gefundene Anzahl sein. Die gefundene Anzahl ist eine Schätzung, wenn die Genauigkeit für die gefundene Anzahl kleiner ist als die tatsächlich gefundene Anzahl. Unabhängig davon, wie Sie die Suchoptionen konfigurieren, liegt das Limit eines Aufrufs von search() bei 10.000 übereinstimmenden Dokumenten.

Wenn mehr Dokumente gefunden wurden, als zurückgegeben werden können, und Sie alle abrufen möchten, müssen Sie die Suche wiederholen. Dies kann mithilfe eines Offsets oder eines Cursors erfolgen, wie weiter unten erläutert.

Bewertete Dokumente

Die Suchergebnisse enthalten eine Liste von ScoredDocuments, die der Abfrage entsprechen. Sie können über die Liste iterieren, um jedes Dokument der Reihe nach zu verarbeiten:

for scored_document in results:
        print(scored_document)

Standardmäßig enthält ein bewertetes Dokument alle Felder des Originaldokuments, das indexiert wurde. Wenn Ihre Abfrageoptionen returned_fields angeben, werden nur diese Felder im Attribut Felder des Dokuments angezeigt. Wenn Sie berechnete Felder durch Angabe von returned_expressions oder snippeted_fields erstellt haben, werden diese separat im Attribut Ausdrücke des Dokuments angezeigt.

Offsets verwenden

Wenn Ihre Suche mehr Dokumente findet, als gleichzeitig zurückgegeben werden können, verwenden Sie einen Offset-Wert, um in der Liste der übereinstimmenden Dokumente zu indexieren. Nehmen wir als Beispiel das Standardabfragelimit von 20 Dokumenten. Nachdem Sie die Suche zum ersten Mal (mit einem Offset-Wert von 0) ausgeführt und die ersten 20 Dokumente abgerufen haben, rufen Sie die nächsten 20 Dokumente mit derselben Suche, aber diesmal mit einem Offset-Wert von 20 ab. Wiederholen Sie die Suche und erhöhen Sie den Offset-Wert jedes Mal um die Anzahl der zurückgegebenen Dokumente:

def query_offset(index, query_string):
    offset = 0

    while True:
        # Build the query using the current offset.
        options = search.QueryOptions(offset=offset)
        query = search.Query(query_string=query_string, options=options)

        # Get the results
        results = index.search(query)

        number_retrieved = len(results.results)
        if number_retrieved == 0:
            break

        # Add the number of documents found to the offset, so that the next
        # iteration will grab the next page of documents.
        offset += number_retrieved

        # Process the matched documents
        for document in results:
            print(document)

Wenn Sie über eine sehr große Ergebnismenge iterieren, können Offsets ineffizient sein.

Cursors verwenden

Sie können auch Cursors verwenden, um eine Teilmenge der Ergebnisse abzurufen. Cursors sind hilfreich, wenn Sie Ihre Suchergebnisse auf aufeinanderfolgenden Seiten darstellen und gewährleisten möchten, dass keine Dokumente übersprungen werden, falls ein Index zwischen Abfragen geändert wurde. Cursors sind auch effizienter, wenn Sie über eine sehr große Ergebnismenge iterieren.

Bei Verwendung von Cursors müssen Sie einen Anfangscursor erstellen und in die Abfrageoptionen einschließen. Es gibt zwei Arten von Cursors, pro Abfrage und pro Ergebnis. Ein Cursor pro Abfrage bewirkt, dass ein separater Cursor dem vom Suchaufruf zurückgegebenen Ergebnisobjekt zugeordnet wird. Ein Cursor pro Ergebnis führt dazu, dass jedem bewerteten Dokument in den Ergebnissen ein Cursor zugeordnet wird.

Cursor pro Abfrage verwenden

Standardmäßig ist ein neu erstellter Cursor ein Cursor pro Abfrage. Dieser Cursor enthält die Position des letzten Dokuments, das in den Suchergebnissen zurückgegeben wurde. Er wird bei jeder Suche aktualisiert. Zum Auflisten aller übereinstimmenden Dokumente in einem Index führen Sie dieselbe Suche aus, bis das Ergebnis einen Nullcursor zurückgibt:

def query_cursor(index, query_string):
    cursor = search.Cursor()

    while cursor:
        # Build the query using the cursor.
        options = search.QueryOptions(cursor=cursor)
        query = search.Query(query_string=query_string, options=options)

        # Get the results and the next cursor
        results = index.search(query)
        cursor = results.cursor

        for document in results:
            print(document)

Cursor pro Ergebnis verwenden

Zum Erstellen von Cursors pro Ergebnis müssen Sie die Property "per_result" des Cursors auf "true" festlegen, wenn Sie den Anfangscursor erstellen. Jedem Dokument, das von der Suche zurückgegeben wird, ist dann ein Cursor zugeordnet. Sie können mithilfe dieses Cursors eine neue Suche angeben, deren Ergebnisse bei einem bestimmten Dokument beginnen. Wenn Sie einen Cursor pro Ergebnis an die Suche übergeben, wird dem Ergebnis selbst kein Cursor pro Abfrage zugeordnet; result.getCursor() gibt null zurück, sodass Sie damit nicht testen können, ob Sie alle Übereinstimmungen abgerufen haben.

def query_per_document_cursor(index, query_string):
    cursor = search.Cursor(per_result=True)

    # Build the query using the cursor.
    options = search.QueryOptions(cursor=cursor)
    query = search.Query(query_string=query_string, options=options)

    # Get the results.
    results = index.search(query)

    document_cursor = None
    for document in results:
        # discover some document of interest and grab its cursor, for this
        # sample we'll just use the first document.
        document_cursor = document.cursor
        break

    # Start the next search from the document of interest.
    if document_cursor is None:
        return

    options = search.QueryOptions(cursor=document_cursor)
    query = search.Query(query_string=query_string, options=options)
    results = index.search(query)

    for document in results:
        print(document)

Cursor speichern und wiederherstellen

Ein Cursor kann als websicherer String serialisiert, gespeichert und dann für die spätere Verwendung wiederhergestellt werden:

def saving_and_restoring_cursor(cursor):
    # Convert the cursor to a web-safe string.
    cursor_string = cursor.web_safe_string
    # Restore the cursor from a web-safe string.
    cursor = search.Cursor(web_safe_string=cursor_string)