Quando uma chamada de consulta é concluída normalmente, devolve o resultado como um objeto Results
. O objeto Results indica quantos documentos correspondentes foram encontrados no índice e quantos documentos correspondentes foram devolvidos. Também inclui uma coleção de ScoredDocuments
a condizer. Normalmente, a coleção 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
// 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...
}
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 coleção de ScoredDocuments
que correspondem à consulta. Pode obter a coleção através do método getResults()
ou iterar sobre os respetivos membros diretamente a partir dos resultados da pesquisa. Ambos os métodos são apresentados aqui:
// 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
}
Por predefinição, um documento com pontuação contém todos os campos do documento original que foi indexado. Se as opções de consulta especificarem setFieldsToReturn
, apenas esses campos aparecem nos resultados quando chama getFields()
no documento. Se usou addExpressionToReturn
ou setFieldsToSnippet
para criar campos calculados, obtenha-os separadamente chamando getExpressions()
no 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:
// 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...
}
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:
// 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 um cursor por resultado
Para criar cursores por resultado, tem de definir a propriedade cursor perResult 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.
// 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 e restaurar cursores
Um cursor pode ser serializado como uma string segura para a Web, guardado e, em seguida, restaurado para utilização posterior:
String cursorString = cursor.toWebSafeString();
// Save the string ... and restore:
Cursor cursor = Cursor.newBuilder().build(cursorString));