Controla los resultados de las búsquedas

Cuando una llamada de consulta se completa con normalidad, muestra el resultado como un objeto SearchResults. El objeto de resultados indica cuántos documentos coincidentes se encontraron en el índice y cuántos se mostraron. También incluye una lista de ScoredDocuments que coinciden. Por lo general, la lista contiene una porción de todos los documentos coincidentes encontrados, ya que la búsqueda muestra solo una cantidad limitada de documentos cada vez que se la llama. Cuando usas un desplazamiento o un cursor, puedes recuperar todos los documentos coincidentes, un subconjunto a la vez.

Resultados

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

Según el valor de la opción de consulta limit, la cantidad de documentos coincidentes que se muestran en el resultado puede ser menor que la cantidad que se encuentra. Recuerda que el número encontrado será una estimación si la exactitud es menor que el número. Sin importar cómo configures las opciones de búsqueda, una llamada search() no encontrará más de 10,000 documentos coincidentes.

Si se encuentran más documentos de los que se muestran y deseas recuperar todos, debes repetir la búsqueda con un desplazamiento o un cursor, como se explica a continuación.

Documentos puntuados

Los resultados de la búsqueda incluirán una lista de ScoredDocuments que coinciden con la consulta. Puedes iterar en la lista para procesar un documento a la vez:

for scored_document in results:
        print(scored_document)

De manera predeterminada, un documento puntuado contiene todos los campos del documento original que se indexó. Si en las opciones de consulta se especificaron returned_fields, solo esos campos aparecen en la propiedad campos del documento. Si creaste campos calculados mediante la especificación de returned_expressions o snippeted_fields, estos aparecerán por separado en la propiedad expresiones del documento.

Usa desplazamientos

Si tu búsqueda encuentra más documentos de los que puedes mostrar al mismo tiempo, usa un desplazamiento para indexarlos a la lista de documentos coincidentes. Por ejemplo, el límite de consulta predeterminado es de 20 documentos. Después de realizar una búsqueda por primera vez (con desplazamiento 0) y recuperar los primeros 20 documentos, configura el desplazamiento en 20 y ejecuta la misma búsqueda de nuevo para recuperar los siguientes 20 documentos. Continúa repitiendo la búsqueda, incrementando el desplazamiento cada vez por el número de documentos mostrados:

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)

Los desplazamientos pueden ser ineficientes cuando se itera sobre un conjunto de resultados muy grande.

Cómo usar cursores

También puede usar cursores para recuperar un subgrupo de resultados. Los cursores son útiles cuando tu intención es presentar los resultados de búsqueda en páginas consecutivas y quieres asegurarte de no omitir ningún documento en caso de que se pueda modificar un índice entre consultas. Además, los cursores son más eficientes cuando iteran sobre un conjunto de resultados muy grande.

Para usar los cursores debes crear un cursor inicial y luego incluirlo en las opciones de consulta. Hay dos tipos de cursores, por-consulta y por-resultado. Un cursor por-consulta hace que un cursor separado se asocie con el objeto de los resultados que muestra la llamada de búsqueda. Un cursor por-resultado hace que un cursor se asocie con cada documento puntuado en los resultados.

Usar un cursor por-consulta

De manera predeterminada, un cursor recién construido es un cursor por-consulta. Este cursor mantiene la posición del último documento mostrado en los resultados de la búsqueda. Se actualiza con cada búsqueda. Para enumerar todos los documentos coincidentes en un índice, ejecuta la misma búsqueda hasta que el resultado muestre un cursor nulo:

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)

Usa un cursor por resultado

Para crear cursores por-resultado, debes configurar la propiedad de cursor per_result en verdadero cuando crees el cursor inicial. Cuando se muestre la búsqueda, todos los documentos tendrán un cursor asociado. Puedes usar ese cursor para especificar una búsqueda nueva con resultados que comiencen con un documento específico. Ten en cuenta que cuando pasas un cursor por resultado a la búsqueda, no existirá un cursor de consulta asociado con el resultado; result.getCursor() se mostrará como nulo, por lo que no puedes usar esta prueba si recuperaste todas las coincidencias.

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)

Guardar y restablecer cursores

Se puede serializar un cursor como una string segura para la Web y, luego, restablecerse a fin de usarlo más tarde:

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)