Итератор поиска
ANN Search имеет максимальное ограничение на количество сущностей, которые могут быть вызваны в одном запросе, и простое использование базового ANN Search может не удовлетворить требованиям крупномасштабного поиска. Для запросов ANN Search, в которых topK превышает 16 384, рекомендуется использовать SearchIterator. В этом разделе мы расскажем о том, как использовать SearchIterator, и о связанных с этим моментах.
Обзор
Запрос Search возвращает результаты поиска, а SearchIterator возвращает итератор. Вы можете вызвать метод next() этого итератора, чтобы получить результаты поиска.
В частности, итераторы SearchIterator можно использовать следующим образом.
Создайте SearchIterator и задайте количество сущностей, возвращаемых по одному поисковому запросу, и общее количество возвращаемых сущностей.
Вызовите метод next() итератора SearchIterator в цикле, чтобы получить результаты поиска в постраничном виде.
Вызовите метод close() итератора, чтобы завершить цикл, если метод next() возвращает пустой результат.
Создание SearchIterator
Следующий фрагмент кода демонстрирует, как создать 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());
В приведенных выше примерах вы задали количество сущностей, возвращаемых за один поиск(batch_size/batchSize), равным 50, а общее количество возвращаемых сущностей(topK) - 20 000.
Использование SearchIterator
Когда итератор SearchIterator готов, вы можете вызвать его метод next(), чтобы получить результаты поиска в постраничном виде.
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);
}
}
В приведенных выше примерах кода вы создали бесконечный цикл, вызвали метод next() в цикле, чтобы сохранить результаты поиска в переменной, и закрыли итератор, когда next() ничего не вернул.