Gestionar los resultados de búsqueda

Cuando una llamada de consulta se completa normalmente, devuelve el resultado como un objeto SearchResults. El objeto de resultados indica cuántos documentos coincidentes se han encontrado en el índice y cuántos se han devuelto. También incluye una lista de ScoredDocuments coincidentes. La lista suele contener una parte de todos los documentos coincidentes encontrados, ya que la búsqueda devuelve un número limitado de documentos cada vez que se llama. Si usas un desplazamiento o un cursor, puedes recuperar todos los documentos coincidentes, un subconjunto cada 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

En función del valor de la limit opción de consulta, el número de documentos coincidentes devueltos en el resultado puede ser inferior al número encontrado. Recuerda que el número encontrado será una estimación si la precisión del número encontrado es inferior al número encontrado. Independientemente de cómo configures las opciones de búsqueda, una llamada search() no encontrará más de 10.000 documentos coincidentes.

Si se han encontrado más documentos de los que se han devuelto y quieres obtenerlos todos, debes repetir la búsqueda con un desplazamiento o un cursor, como se explica a continuación.

Documentos con puntuación

En los resultados de búsqueda se incluirá una lista de ScoredDocuments que coincidan con la consulta. Puedes iterar en la lista para procesar cada documento por turnos:

for scored_document in results:
        print(scored_document)

De forma predeterminada, un documento con puntuación contiene todos los campos del documento original que se ha indexado. Si en las opciones de consulta se ha especificado returned_fields, solo aparecerán esos campos en la propiedad fields del documento. Si has creado algún campo calculado especificando returned_expressions o snippeted_fields, aparecerá por separado en la propiedad expressions del documento.

Usar desplazamientos

Si la búsqueda encuentra más documentos de los que puedes devolver a la vez, usa un desplazamiento para indexar la lista de documentos coincidentes. Por ejemplo, el límite de consultas predeterminado es de 20 documentos. Después de ejecutar una búsqueda por primera vez (con el desplazamiento 0) y obtener los primeros 20 documentos, obtén los 20 siguientes configurando el desplazamiento en 20 y volviendo a ejecutar la misma búsqueda. Repite la búsqueda y aumenta el desplazamiento cada vez en el número de documentos devueltos:

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 al iterar en un conjunto de resultados muy grande.

Usar cursores

También puedes usar cursores para obtener un subintervalo de resultados. Los cursores son útiles cuando quieres presentar los resultados de búsqueda en páginas consecutivas y quieres asegurarte de que no se omita ningún documento en el caso de que se modifique un índice entre consultas. Los cursores también son más eficientes cuando se itera en un conjunto de resultados muy grande.

Para usar cursores, debes crear un cursor inicial e incluirlo en las opciones de la consulta. Hay dos tipos de cursores: por consulta y por resultado. Un cursor por consulta hace que se asocie un cursor independiente al objeto de resultados devuelto por la llamada de búsqueda. Un cursor por resultado hace que se asocie un cursor a cada documento puntuado de los resultados.

Usar un cursor por consulta

De forma predeterminada, un cursor recién creado es un cursor por consulta. Este cursor contiene la posición del último documento devuelto en los resultados de la búsqueda. Se actualiza con cada búsqueda. Para enumerar todos los documentos que coinciden en un índice, ejecuta la misma búsqueda hasta que el resultado devuelva 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)

Usar un cursor por resultado

Para crear cursores por resultado, debe definir la propiedad per_result del cursor en true al crear el cursor inicial. Cuando se devuelvan los resultados de la búsqueda, cada documento tendrá un cursor asociado. Puedes usar ese cursor para especificar una nueva búsqueda con resultados que empiecen por un documento concreto. Ten en cuenta que, cuando envías un cursor por resultado a la búsqueda, no habrá ningún cursor por consulta asociado al resultado en sí. result.getCursor() devolverá null, por lo que no podrás usarlo para comprobar si has obtenido 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 restaurar cursores

Un cursor se puede serializar como una cadena segura para la Web, guardar y, a continuación, restaurar para usarlo más adelante:

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)