Iterador de pesquisa
A Pesquisa ANN tem um limite máximo para o número de entidades que podem ser recuperadas numa única consulta, e a simples utilização da Pesquisa ANN básica pode não satisfazer as exigências da recuperação em grande escala. Para pedidos de Pesquisa ANN em que topK excede 16.384, é aconselhável considerar a utilização do Iterador de Pesquisa. Esta secção apresenta a forma de utilizar o SearchIterator e as considerações relacionadas.
Visão geral
Um pedido de Pesquisa devolve resultados de pesquisa, enquanto um SearchIterator devolve um iterador. Você pode chamar o método next() desse iterador para obter os resultados da pesquisa.
Especificamente, pode utilizar os SearchIterators da seguinte forma.
Criar um SearchIterator e definir o número de entidades a devolver por pedido de pesquisa e o número total de entidades a devolver.
Chame o método next() do SearchIterator em um loop para obter o resultado da pesquisa de forma paginada.
Chamar o método close() do iterador para terminar o ciclo se o método next() devolver um resultado vazio.
Criar SearchIterator
O seguinte excerto de código demonstra como criar um SearchIterator.
from pymilvus import connections, Collection
connections.connect(
uri="http://localhost:19530",
token="root:Milvus"
)
# create iterator
query_vectors = [
[0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]]
collection = Collection("iterator_collection")
iterator = collection.search_iterator(
data=query_vectors,
anns_field="vector",
param={"metric_type": "L2", "params": {"nprobe": 16}},
# highlight-next-line
batch_size=50,
output_fields=["color"],
# highlight-next-line
limit=20000
)
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.orm.iterator.SearchIterator;
import io.milvus.v2.common.IndexParam.MetricType;
import io.milvus.v2.service.vector.request.data.FloatVec;
import java.util.*;
MilvusClientV2 client = new MilvusClientV2(ConnectConfig.builder()
.uri("http://localhost:19530")
.token("root:Milvus")
.build());
FloatVec queryVector = new FloatVec(new float[]{0.3580376395471989f, -0.6023495712049978f, 0.18414012509913835f, -0.26286205330961354f, 0.9029438446296592f});
SearchIterator searchIterator = client.searchIterator(SearchIteratorReq.builder()
.collectionName("iterator_collection")
.vectors(Collections.singletonList(queryVector))
.vectorFieldName("vector")
.batchSize(500L)
.outputFields(Lists.newArrayList("color"))
.topK(20000)
.metricType(IndexParam.MetricType.COSINE)
.build());
Nos exemplos acima, você definiu o número de entidades a retornar por pesquisa(batch_size/batchSize) como 50 e o número total de entidades a retornar(topK) como 20.000.
Usar o SearchIterator
Quando o SearchIterator estiver pronto, pode chamar o seu método next() para obter os resultados da pesquisa de uma forma paginada.
results = []
while True:
# highlight-next-line
result = iterator.next()
if not result:
# highlight-next-line
iterator.close()
break
for hit in result:
results.append(hit.to_dict())
import io.milvus.response.QueryResultsWrapper;
while (true) {
List<QueryResultsWrapper.RowRecord> res = searchIterator.next();
if (res.isEmpty()) {
searchIterator.close();
break;
}
for (QueryResultsWrapper.RowRecord record : res) {
System.out.println(record);
}
}
Nos exemplos de código acima, criou um ciclo infinito e chamou o método next() no ciclo para armazenar os resultados da pesquisa numa variável e fechou o iterador quando next() não devolve nada.