Controla los resultados de las búsquedas

Cuando una llamada de consulta se completa con normalidad, muestra el resultado como un objeto Results. El objeto Results indica cuántos documentos coincidentes se encontraron en el índice y cuántos se mostraron. También incluye una colección de ScoredDocuments coincidentes. Por lo general, la colección 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

// index and query have already been defined ...
try {
    Results<ScoredDocument> result = index.search(query);
    long totalMatches = result.getNumberFound();
    int numberOfDocsReturned = result.getNumberReturned();
    Collection<ScoredDocument> listOfDocs = result.getResults();
} catch (SearchException e) {
    // handle exception...
}

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 colección de ScoredDocuments que coincidan con la consulta. Puedes recuperar la colección mediante el método getResults() o iterar sobre sus miembros directamente a partir de los resultados de la búsqueda. Ambos métodos se muestran aquí:

// index and query have already been defined ...
Results<ScoredDocument> result = index.search(query);

// Grab the collection for later use:
Collection<ScoredDocument> theDocs = result.getResults();

// Alternatively, iterate over the results directly:
for (ScoredDocument doc : result) {
    // do work
}

De manera predeterminada, un documento puntuado contiene todos los campos del documento original que se indexó. Si las opciones de consulta especificaron setFieldsToReturn, solo esos campos aparecerán en los resultados cuando llames a getFields() en el documento. Si usaste addExpressionToReturn o setFieldsToSnippet para crear campos calculados, llama a getExpressions() en el documento a fin de recuperarlos por separado.

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:

// index and queryString have already been defined

try {
    int numberRetrieved = 0;
    int offset = 0;
    do {
        // build options and query
        QueryOptions options = QueryOptions.newBuilder()
            .setOffset(offset)
            .build();
        Query query = Query.newBuilder().setOptions(options).build(queryString);

        // search at least once
        Results<ScoredDocument> result = index.search(query);
        numberRetrieved = result.getNumberReturned();
        if (numberRetrieved > 0) {
            offset += numberRetrieved;
            // process the matched docs
        }

    }
    while (numberRetrieved > 0);
} catch (SearchException e) {
    // handle exception...
}

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:

// index and queryString have already been defined

try {
    // create the initial cursor
    Cursor cursor = Cursor.newBuilder().build();

    do {
        // build options and query
        QueryOptions options = QueryOptions.newBuilder()
            .setCursor(cursor)
            .build();
        Query query = Query.newBuilder().setOptions(options).build(queryString);

        // search at least once
        Results<ScoredDocument> result = index.search(query);
        int numberRetrieved = result.getNumberReturned();
        cursor = result.getCursor();

        if (numberRetrieved > 0) {
            // process the matched docs
        }

    }
    while (cursor != null);
    // all done!
} catch (SearchException e) {
    // handle exception...
}

Usar un cursor por-resultado

Para crear un cursor por-resultado, debes configurar la propiedad perResult en true cuando crees el cursor inicial. Cuando se muestre la búsqueda, cada documento tendrá 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.

// index and queryString have already been defined

try {
    // create an initial per-result cursor
    Cursor cursor = Cursor.newBuilder().setPerResult(true).build();
    // build options and query
    QueryOptions options = QueryOptions.newBuilder()
        .setCursor(cursor)
        .build();
    Query query = Query.newBuilder().setOptions(options).build(queryString);
    Results<ScoredDocument> result = index.search(query);

    // process the matched docs
    cursor = null;
    for (ScoredDocument doc : result) {
        // discover some document of interest and grab its cursor
        if (...)
            cursor = doc.getCursor();
     }

    // Start the next search from the document of interest
    if (cursor != null) {
        options = QueryOptions.newBuilder()
            .setCursor(cursor)
            .build();
        query = Query.newBuilder().setOptions(options).build(queryString);
        result = index.search(query);
    }
} catch (SearchException e) {
    // handle exception
}

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:

String cursorString = cursor.toWebSafeString();
// Save the string ... and restore:
Cursor cursor = Cursor.newBuilder().build(cursorString));