Processar resultados de pesquisa

Quando uma chamada de consulta é concluída normalmente, o resultado é um objeto SearchResults. O objeto de resultados informa quantos documentos correspondentes foram encontrados no índice e quantos documentos correspondentes foram retornados. Também inclui uma lista de ScoredDocuments correspondentes. A lista geralmente contém uma parte de todos os documentos correspondentes encontrados, uma vez que a pesquisa retorna um número limitado de documentos cada vez que é chamada. Ao usar um desvio ou um cursor, você pode recuperar todos os documentos correspondentes, um subconjunto por 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

Dependendo do valor da opção de consulta limit, o número de documentos correspondentes retornados no resultado pode ser inferior ao encontrado. Lembre-se de que o número encontrado será uma estimativa se a precisão dele for menor que o valor. Independentemente de como você configurar as opções de pesquisa, uma chamada search() não encontrará mais que 10 mil documentos correspondentes.

Se forem encontrados mais documentos do que os retornados e você quiser recuperar todos eles, precisará repetir a pesquisa usando um desvio ou um cursor, conforme explicado abaixo.

Documentos pontuados

Os resultados da pesquisa incluirão uma lista de ScoredDocuments que correspondem à consulta. Você pode iterar na lista para processar um documento por vez:

for scored_document in results:
        print(scored_document)

Por padrão, um documento pontuado contém todos os campos do documento original indexados. Se as opções de consulta especificarem returned_fields, somente esses campos aparecerão na propriedade campos do documento. Se você tiver criado campos computados especificando returned_expressions ou snippeted_fields, eles serão exibidos separadamente na propriedade expressões do documento.

Como usar desvios

Se a pesquisa encontrar mais documentos do que é possível retornar de imediato, use um desvio a ser indexado na lista de documentos correspondentes. Por exemplo, o limite de consulta padrão é 20 documentos. Depois de executar uma pesquisa pela primeira vez (com o desvio 0) e recuperar os 20 primeiros documentos, recupere os 20 documentos seguintes definindo o desvio como 20 e executando a mesma pesquisa novamente. Continue repetindo a pesquisa, incrementando o deslocamento a cada vez com o número de documentos retornados:

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)

Os deslocamentos podem ser ineficientes na iteração sobre um conjunto de resultados muito grande.

Como usar cursores

Você também pode usar cursores para recuperar um subintervalo de resultados. Os cursores são úteis quando você pretende apresentar os resultados da pesquisa em páginas consecutivas e quer ter certeza de que não pulará nenhum documento no caso em que um índice seja modificado entre consultas. Os cursores também são mais eficientes na iteração em um conjunto de resultados muito grande.

Para usar cursores, é preciso criar um cursor inicial e incluí-lo nas opções de consulta. Há dois tipos de cursores, por consulta e por resultado. Um cursor por consulta faz com que um cursor separado seja associado ao objeto de resultado retornado pela chamada de pesquisa. Um cursor por resultado faz com que um cursor seja associado a cada documento pontuado nos resultados.

Como usar um cursor por consulta

Por padrão, um cursor recém-construído é um cursor por consulta. Ele mantém a posição do último documento retornado nos resultados da pesquisa e é atualizado a cada pesquisa. Para enumerar todos os documentos correspondentes em um índice, execute a mesma pesquisa até o resultado retornar um 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)

Como usar um cursor por resultado

Para criar cursores por resultado, é preciso definir a propriedade de cursor “per_result” como “true” ao criar o cursor inicial. Quando a pesquisa retornar, haverá um cursor associado a cada documento. Você pode usar esse cursor para especificar uma nova pesquisa com resultados que começam com um documento específico. Observe que, quando você passa um cursor por resultado para a pesquisa, não haverá nenhum cursor por consulta associado ao resultado. result.getCursor() retornará nulo, então não é possível usar isso para testar se todas as correspondências foram recuperadas.

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)

Como salvar e restaurar cursores

Um cursor pode ser serializado como uma string segura na Web e, em seguida, restaurado para uso posterior:

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)