milvus-logo
LFAI
Home
  • Guia do utilizador

Com Iteradores

Milvus fornece iteradores de pesquisa e consulta para iterar através de um grande volume de entidades. Uma vez que o Milvus limita o TopK a 16384, os utilizadores podem utilizar iteradores para devolver grandes números ou mesmo entidades inteiras numa coleção em modo batch.

Visão geral

Os iteradores são uma ferramenta eficiente para pesquisar uma coleção inteira ou iterar através de um grande volume de entidades, especificando valores de chave primária ou uma expressão de filtro. Em comparação com uma chamada de pesquisa ou consulta com parâmetros de deslocamento e limite, a utilização de iteradores é mais eficiente e escalável.

Vantagens da utilização de iteradores

  • Simplicidade: Elimina as complexas definições de offset e limite.

  • Eficiência: Fornece recuperação escalável de dados, buscando apenas os dados necessários.

  • Consistência: Garante um tamanho de conjunto de dados consistente com filtros booleanos.

notas

  • Esta funcionalidade está disponível para o Milvus 2.3.x ou posterior.

Preparações

O seguinte passo de preparação liga-se ao Milvus e insere entidades geradas aleatoriamente numa coleção.

Passo 1: Criar uma coleção

Use MilvusClient para se ligar ao servidor Milvus e create_collection() para criar uma coleção.

Utilize MilvusClientV2 para se ligar ao servidor Milvus e createCollection() para criar uma coleção.

from pymilvus import MilvusClient

# 1. Set up a Milvus client
client = MilvusClient(
    uri="http://localhost:19530"
)

# 2. Create a collection
client.create_collection(
    collection_name="quick_setup",
    dimension=5,
)
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import io.milvus.orm.iterator.QueryIterator;
import io.milvus.orm.iterator.SearchIterator;
import io.milvus.response.QueryResultsWrapper;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.common.ConsistencyLevel;
import io.milvus.v2.common.IndexParam;
import io.milvus.v2.service.collection.request.CreateCollectionReq;
import io.milvus.v2.service.collection.request.DropCollectionReq;
import io.milvus.v2.service.vector.request.*;
import io.milvus.v2.service.vector.request.data.FloatVec;
import io.milvus.v2.service.vector.response.InsertResp;
import io.milvus.v2.service.vector.response.QueryResp;

import java.util.*;

String CLUSTER_ENDPOINT = "http://localhost:19530";

// 1. Connect to Milvus server
ConnectParam connectParam = ConnectParam.newBuilder()
        .withUri(CLUSTER_ENDPOINT)
        .build();

MilvusServiceClient client  = new MilvusServiceClient(connectParam);

// 2. Create a collection
CreateCollectionReq quickSetupReq = CreateCollectionReq.builder()
        .collectionName("quick_setup")
        .dimension(5)
        .build();
client.createCollection(quickSetupReq);

Passo 2: Inserir entidades geradas aleatoriamente

Utilize insert() para inserir entidades na coleção.

Utilizar insert() para inserir entidades na coleção.

# 3. Insert randomly generated vectors 
colors = ["green", "blue", "yellow", "red", "black", "white", "purple", "pink", "orange", "brown", "grey"]
data = []

for i in range(10000):
    current_color = random.choice(colors)
    current_tag = random.randint(1000, 9999)
    data.append({
        "id": i,
        "vector": [ random.uniform(-1, 1) for _ in range(5) ],
        "color": current_color,
        "tag": current_tag,
        "color_tag": f"{current_color}_{str(current_tag)}"
    })

print(data[0])

# Output
#
# {
#     "id": 0,
#     "vector": [
#         -0.5705990742218152,
#         0.39844925120642083,
#         -0.8791287928610869,
#         0.024163154953680932,
#         0.6837669917169638
#     ],
#     "color": "purple",
#     "tag": 7774,
#     "color_tag": "purple_7774"
# }

res = client.insert(
    collection_name="quick_setup",
    data=data,
)

print(res)

# Output
#
# {
#     "insert_count": 10000,
#     "ids": [
#         0,
#         1,
#         2,
#         3,
#         4,
#         5,
#         6,
#         7,
#         8,
#         9,
#         "(9990 more items hidden)"
#     ]
# }
// 3. Insert randomly generated vectors into the collection
List<String> colors = Arrays.asList("green", "blue", "yellow", "red", "black", "white", "purple", "pink", "orange", "brown", "grey");
List<JsonObject> data = new ArrayList<>();
Gson gson = new Gson();
for (int i=0; i<10000; i++) {
    Random rand = new Random();
    String current_color = colors.get(rand.nextInt(colors.size()-1));
    JsonObject row = new JsonObject();
    row.addProperty("id", (long) i);
    row.add("vector", gson.toJsonTree(Arrays.asList(rand.nextFloat(), rand.nextFloat(), rand.nextFloat(), rand.nextFloat(), rand.nextFloat())));
    row.addProperty("color_tag", current_color + "_" + (rand.nextInt(8999) + 1000));
    data.add(row);
}

InsertResp insertR = client.insert(InsertReq.builder()
        .collectionName("quick_setup")
        .data(data)
        .build());
System.out.println(insertR.getInsertCnt());

// Output
// 10000

Pesquisa com iterador

Os iteradores tornam as pesquisas por semelhança mais escaláveis.

Para pesquisar com um iterador, chame o método search_iterator():

Para pesquisar com um iterador, chame o método searchIterator():

  1. Inicialize o iterador de pesquisa para definir os parâmetros de pesquisa e os campos de saída.

  2. Utilize o método next() dentro de um loop para paginar os resultados da pesquisa.

    • Se o método retornar uma matriz vazia, o loop termina e não há mais páginas disponíveis.

    • Todos os resultados contêm os campos de saída especificados.

  3. Chame manualmente o método close() para fechar o iterador quando todos os dados tiverem sido recuperados.

from pymilvus import Collection,connections

# 4. Search with iterator
connections.connect(host="127.0.0.1", port=19530)
collection = Collection("quick_setup")

query_vectors = [[0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]]
search_params = {
    "metric_type": "IP",
    "params": {"nprobe": 10}
}

iterator = collection.search_iterator(
    data=query_vectors,
    anns_field="vector",
    batch_size=10,
    param=search_params,
    output_fields=["color_tag"],
    limit=300
)
# search 300 entities totally with 10 entities per page

results = []

while True:
    result = iterator.next()
    if not result:
        iterator.close()
        break
        
    results.extend(result)
    
    for hit in result:
        results.append(hit.to_dict())

print(results)

# Output
#
# [
#     {
#         "id": 1756,
#         "distance": 2.0642056465148926,
#         "entity": {
#             "color_tag": "black_9109"
#         }
#     },
#     {
#         "id": 6488,
#         "distance": 1.9437453746795654,
#         "entity": {
#             "color_tag": "purple_8164"
#         }
#     },
#     {
#         "id": 3338,
#         "distance": 1.9107104539871216,
#         "entity": {
#             "color_tag": "brown_8121"
#         }
#     }
# ]
// 4. Search with iterators
SearchIteratorReq iteratorReq = SearchIteratorReq.builder()
        .collectionName("quick_setup")
        .vectorFieldName("vector")
        .batchSize(10L)
        .vectors(Collections.singletonList(new FloatVec(Arrays.asList(0.3580376395471989f, -0.6023495712049978f, 0.18414012509913835f, -0.26286205330961354f, 0.9029438446296592f))))
        .params("{\"level\": 1}")
        .metricType(IndexParam.MetricType.COSINE)
        .outputFields(Collections.singletonList("color_tag"))
        .topK(300)
        .build();

SearchIterator searchIterator = client.searchIterator(iteratorReq);

List<QueryResultsWrapper.RowRecord> results = new ArrayList<>();
while (true) {
    List<QueryResultsWrapper.RowRecord> batchResults = searchIterator.next();
    if (batchResults.isEmpty()) {
        searchIterator.close();
        break;
    }

    results.addAll(batchResults);
}
System.out.println(results.size());

// Output
// 300
Parâmetro Descrição
data Uma lista de incorporações vectoriais.
Milvus procura as incorporações vectoriais mais semelhantes às especificadas.
anns_field O nome do campo vetorial na coleção atual.
batch_size O número de entidades a devolver sempre que chamar next() no iterador atual.
O valor predefinido é 1000. Defina-o para um valor adequado para controlar o número de entidades a retornar por iteração.
param As definições dos parâmetros específicos desta operação.
  • metric_type: O tipo de métrica aplicado a esta operação. Este deve ser o mesmo que o utilizado quando indexa o campo vetorial especificado acima. Os valores possíveis são L2, IP, COSINE, JACCARD, HAMMING.
  • params: Parâmetros adicionais. Para obter detalhes, consulte search_iterator().
output_fields Uma lista de nomes de campo para incluir em cada entidade em retorno.
O valor padrão é None. Se não for especificado, apenas o campo primário será incluído.
limit O número total de entidades a serem retornadas.
O valor padrão é -1, indicando que todas as entidades correspondentes serão retornadas.
Parâmetro Descrição
withCollectionName Define o nome da coleção. O nome da coleção não pode estar vazio ou ser nulo.
withVectorFieldName Definir o campo do vetor de destino por nome. O nome do campo não pode estar vazio ou ser nulo.
withVectors Definir os vectores de destino. São permitidos até 16384 vectores.
withBatchSize O número de entidades a retornar cada vez que você chamar next() no iterador atual.
O valor padrão é 1000. Defina-o para um valor adequado para controlar o número de entidades a devolver por iteração.
withParams Especifica os parâmetros de pesquisa no formato JSON. Para obter mais informações, consulte searchIterator().

Consultar com um iterador

Para consultar com um iterador, chame o método query_iterator():

Para pesquisar com um iterador, chame o método queryIterator():

# 6. Query with iterator
iterator = collection.query_iterator(
    batch_size=10, # Controls the size of the return each time you call next()
    expr="color_tag like \"brown_8\"",
    output_fields=["color_tag"]
)

results = []

while True:
    result = iterator.next()
    if not result:
        iterator.close()
        break
        
    results.extend(result)
    
# 8. Check the search results
print(len(results))

print(results[:3])

# Output
#
# [
#     {
#         "color_tag": "brown_8785",
#         "id": 94
#     },
#     {
#         "color_tag": "brown_8568",
#         "id": 176
#     },
#     {
#         "color_tag": "brown_8721",
#         "id": 289
#     }
# ]
// 5. Query with iterators
QueryIterator queryIterator = client.queryIterator(QueryIteratorReq.builder()
        .collectionName("quick_setup")
        .expr("color_tag like \"brown_8%\"")
        .batchSize(50L)
        .outputFields(Arrays.asList("vector", "color_tag"))
        .build());

results.clear();
while (true) {
    List<QueryResultsWrapper.RowRecord> batchResults = queryIterator.next();
    if (batchResults.isEmpty()) {
        queryIterator.close();
        break;
    }

    results.addAll(batchResults);
}

System.out.println(results.subList(0, 3));

// Output
// [
//  [color_tag:brown_8975, vector:[0.93425006, 0.42161798, 0.1603949, 0.86406225, 0.30063087], id:104],
//  [color_tag:brown_8292, vector:[0.075261295, 0.51725155, 0.13842249, 0.13178307, 0.90713704], id:793],
//  [color_tag:brown_8763, vector:[0.80366623, 0.6534371, 0.6446101, 0.094082, 0.1318503], id:1157]
// ]

Parâmetro Descrição
batch_size O número de entidades a devolver sempre que chamar next() no iterador atual.
O valor predefinido é 1000. Defina-o para um valor adequado para controlar o número de entidades a devolver por iteração.
expr Uma condição de filtragem escalar para filtrar entidades correspondentes.
O valor padrão é Nenhum, indicando que a filtragem escalar é ignorada. Para criar uma condição de filtragem escalar, consulte Regras de expressão booleana.
output_fields Uma lista de nomes de campo para incluir em cada entidade em retorno.
O valor padrão é None. Se não for especificado, apenas o campo primário será incluído.
limit O número total de entidades a devolver.
O valor predefinido é -1, indicando que todas as entidades correspondentes serão devolvidas.
Parâmetro Descrição
withCollectionName Define o nome da coleção. O nome da coleção não pode estar vazio ou ser nulo.
withExpr Define a expressão para consultar entidades. Para criar uma condição de filtragem escalar, consulte Regras de expressão booleana.
withBatchSize O número de entidades a retornar cada vez que você chamar next() no iterador atual.
O valor padrão é 1000. Defina-o para um valor adequado para controlar o número de entidades a serem retornadas por iteração.
addOutField Especifica um campo escalar de saída (opcional).

Traduzido porDeepLogo

Try Managed Milvus for Free

Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.

Get Started
Feedback

Esta página foi útil?