Gestione dei risultati di ricerca

Quando una chiamata di query viene completata normalmente, restituisce il risultato come oggetto Results. L'oggetto Results indica quanti documenti corrispondenti sono stati trovati nell'indice e quanti documenti corrispondenti sono stati restituiti. Inoltre, include una raccolta di ScoredDocuments corrispondenti. La raccolta di solito contiene una parte di tutti i documenti corrispondenti trovati, poiché la ricerca restituisce un numero limitato di documenti ogni volta che viene richiamata. Utilizzando un offset o un cursore, puoi recuperare tutti i documenti corrispondenti, un sottoinsieme alla volta.

Risultati

// 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...
}

A seconda del valore dell'opzione di query di limit, il numero di documenti corrispondenti restituiti nel risultato potrebbe essere inferiore al numero trovato. Ricorda che il numero trovato sarà una stima se l'accuratezza del numero rilevato è inferiore a quello trovato. Indipendentemente da come configuri le opzioni di ricerca, una chiamata search() non troverà più di 10.000 documenti corrispondenti.

Se sono stati trovati più documenti di quelli restituiti e desideri recuperarli tutti, devi ripetere la ricerca utilizzando un offset o un cursore, come spiegato di seguito.

Documenti con punteggio

I risultati di ricerca includeranno una raccolta di ScoredDocuments che corrispondono alla query. Puoi recuperare la raccolta utilizzando il metodo getResults() o ripetere l'iterazione dei suoi membri direttamente dai risultati di ricerca stessi. Entrambi i metodi sono mostrati qui:

// 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
}

Per impostazione predefinita, un documento con punteggio contiene tutti i campi del documento originale che è stato indicizzato. Se le opzioni di query specificano setFieldsToReturn, solo quei campi verranno visualizzati nei risultati quando chiami getFields() nel documento. Se hai utilizzato addExpressionToReturn o setFieldsToSnippet per creare campi calcolati, recuperali separatamente chiamando getExpressions() sul documento.

Utilizzare gli offset

Se la ricerca trova più documenti di quelli che puoi restituire contemporaneamente, utilizza un offset per indicizzare l'elenco dei documenti corrispondenti. Ad esempio, il limite di query predefinito è di 20 documenti. Dopo aver eseguito una ricerca per la prima volta (con offset 0) e recuperato i primi 20 documenti, recupera i 20 documenti successivi impostando l'offset su 20 ed eseguendo di nuovo la stessa ricerca. Continua a ripetere la ricerca, incrementando ogni volta l'offset del numero di documenti restituiti:

// 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...
}

Gli offset possono essere inefficienti quando si esegue l'iterazione su un set di risultati molto grande.

Utilizzo dei cursori

Puoi anche utilizzare i cursori per recuperare un sottointervallo di risultati. I cursori sono utili quando intendi presentare i risultati di ricerca in pagine consecutive e vuoi assicurarti di non saltare nessun documento nel caso in cui un indice possa essere modificato tra una query e l'altra. I cursori sono inoltre più efficienti quando si eseguono l'iterazione su un set di risultati molto grande.

Per utilizzare i cursori, devi creare un cursore iniziale e includerlo nelle opzioni della query. Esistono due tipi di cursori: per query e per risultato. Un cursore di query comporta l'associazione di un cursore separato all'oggetto dei risultati restituito dalla chiamata di ricerca. Un cursore per risultato fa sì che un cursore venga associato a ogni documento con punteggio nei risultati.

Utilizzare un cursore di query

Per impostazione predefinita, un cursore di nuova creazione è un cursore di query. Questo cursore occupa la posizione dell'ultimo documento restituito nei risultati della ricerca. Viene aggiornato a ogni ricerca. Per enumerare tutti i documenti corrispondenti in un indice, esegui la stessa ricerca finché il risultato non restituisce un cursore nullo:

// 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...
}

Utilizzare un cursore per risultato

Per creare cursori per risultato, devi impostare la proprietà cursore perResult su true quando crei il cursore iniziale. Quando viene restituita la ricerca, a ogni documento è associato un cursore. Puoi utilizzare il cursore per specificare una nuova ricerca con risultati che iniziano con un documento specifico. Tieni presente che quando passi un cursore per risultato per la ricerca, non ci sarà alcun cursore di query associato al risultato stesso; result.getCursor() restituirà null, quindi non puoi utilizzarlo per verificare se hai recuperato tutte le corrispondenze.

// 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
}

Salvataggio e ripristino dei cursori

Un cursore può essere serializzato come stringa sicura per il web, salvato e poi ripristinato per un utilizzo futuro:

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