Processamento de resultados da pesquisa

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

Dependendo do valor da limit opção de consulta, o número de documentos correspondentes devolvidos no resultado pode ser inferior ao número encontrado. Lembre-se de que o número encontrado é uma estimativa se a precisão do número encontrado for inferior ao número encontrado. Independentemente da forma como configura as opções de pesquisa, uma chamada search() não encontra mais de 10 000 documentos correspondentes.

Se foram encontrados mais documentos do que os devolvidos e quiser recuperá-los todos, tem de repetir a pesquisa usando um deslocamento ou um cursor, conforme explicado abaixo.

Documentos classificados

Os resultados da pesquisa incluem uma lista de ScoredDocuments que correspondem à consulta. Pode iterar a lista para processar cada documento por sua vez:

for scored_document in results:
        print(scored_document)

Por predefinição, um documento com pontuação contém todos os campos do documento original que foi indexado. Se as suas opções de consulta especificarem returned_fields, apenas esses campos aparecem na propriedade fields do documento. Se criou campos calculados especificando returned_expressions ou snippeted_fields, estes aparecem separadamente na propriedade expressions do documento.

Usar desvios

Se a sua pesquisa encontrar mais documentos do que os que pode devolver de uma só vez, use um deslocamento para indexar a lista de documentos correspondentes. Por exemplo, o limite de consultas predefinido é de 20 documentos. Depois de executar uma pesquisa pela primeira vez (com o deslocamento 0) e recuperar os primeiros 20 documentos, recupere os 20 documentos seguintes definindo o deslocamento para 20 e executando a mesma pesquisa novamente. Continue a repetir a pesquisa, incrementando o deslocamento de cada vez pelo número de documentos devolvidos:

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 desvios podem ser ineficientes quando se iteram sobre um conjunto de resultados muito grande.

Usar cursores

Também pode usar cursores para obter um subintervalo de resultados. Os cursores são úteis quando pretende apresentar os resultados da pesquisa em páginas consecutivas e quer certificar-se de que não ignora nenhum documento no caso de um índice poder ser modificado entre consultas. Os cursores também são mais eficientes quando iteram num conjunto de resultados muito grande.

Para usar cursores, tem de criar um cursor inicial e incluí-lo nas opções de consulta. Existem dois tipos de cursores: por consulta e por resultado. Um cursor por consulta faz com que seja associado um cursor separado ao objeto de resultados devolvido pela chamada de pesquisa. Um cursor por resultado faz com que um cursor seja associado a todos os documentos classificados nos resultados.

Usar um cursor por consulta

Por predefinição, um cursor recém-construído é um cursor por consulta. Este cursor contém a posição do último documento devolvido nos resultados da pesquisa. É atualizado com cada pesquisa. Para enumerar todos os documentos correspondentes num índice, execute a mesma pesquisa até o resultado devolver 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)

Usar um cursor por resultado

Para criar cursores por resultado, tem de definir a propriedade per_result do cursor como verdadeira quando cria o cursor inicial. Quando a pesquisa é devolvida, cada documento tem um cursor associado. Pode usar esse cursor para especificar uma nova pesquisa com resultados que começam com um documento específico. Tenha em atenção que, quando passa um cursor por resultado para a pesquisa, não existe nenhum cursor por consulta associado ao próprio resultado. result.getCursor() devolve nulo, pelo que não pode usar esta opção para testar se recuperou todas as correspondências.

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 e restaurar cursores

Um cursor pode ser serializado como uma string segura para a Web, guardado e, em seguida, restaurado para utilização 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)