Iteratore di ricerca
La ricerca ANN ha un limite massimo al numero di entità che possono essere richiamate in una singola query e il semplice utilizzo della ricerca ANN di base potrebbe non soddisfare le richieste di recupero su larga scala. Per le richieste di ricerca ANN in cui topK supera i 16.384, è consigliabile considerare l'uso del SearchIterator. Questa sezione presenta come utilizzare il SearchIterator e le relative considerazioni.
Panoramica
Una richiesta di ricerca restituisce i risultati della ricerca, mentre un SearchIterator restituisce un iteratore. È possibile chiamare il metodo next() di questo iteratore per ottenere i risultati della ricerca.
In particolare, si possono usare i SearchIterator come segue.
Creare un SearchIterator e impostare il numero di entità da restituire per ogni richiesta di ricerca e il numero totale di entità da restituire.
Chiamare il metodo next() del SearchIterator in un ciclo per ottenere i risultati della ricerca in modo impaginato.
Chiamare il metodo close() dell'iteratore per terminare il ciclo se il metodo next() restituisce un risultato vuoto.
Creare un iteratore di ricerca
Il seguente frammento di codice mostra come creare un iteratore di ricerca.
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());
Negli esempi precedenti, il numero di entità da restituire per ogni ricerca(batch_size/batchSize) è stato impostato a 50 e il numero totale di entità da restituire(topK) a 20.000.
Utilizzare SearchIterator
Una volta che il SearchIterator è pronto, si può chiamare il suo metodo next() per ottenere i risultati della ricerca in modo impaginato.
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);
}
}
Negli esempi di codice precedenti, si è creato un ciclo infinito e si è chiamato il metodo next() nel ciclo per memorizzare i risultati della ricerca in una variabile e chiudere l'iteratore quando next() non restituisce nulla.