milvus-logo
LFAI
Home
  • Guía del usuario

Con iteradores

Milvus proporciona iteradores de búsqueda y consulta para iterar a través de un gran volumen de entidades. Dado que Milvus limita TopK a 16384, los usuarios pueden utilizar iteradores para devolver grandes números o incluso entidades enteras en una colección en modo por lotes.

Visión general

Los iteradores son una herramienta eficaz para escanear una colección completa o iterar a través de un gran volumen de entidades especificando valores de clave primaria o una expresión de filtro. En comparación con una llamada de búsqueda o consulta con parámetros de desplazamiento y límite, el uso de iteradores es más eficiente y escalable.

Ventajas del uso de iteradores

  • Simplicidad: Elimina los complejos parámetros de desplazamiento y límite.

  • Eficacia: Proporciona una recuperación de datos escalable al obtener sólo los datos necesarios.

  • Coherencia: Garantiza un tamaño coherente del conjunto de datos con filtros booleanos.

notas

  • Esta función está disponible para Milvus 2.3.x o posterior.

Preparativos

El siguiente paso de preparación se conecta a Milvus e inserta entidades generadas aleatoriamente en una colección.

Paso 1: Crear una colección

Utilice MilvusClient para conectarse al servidor Milvus y create_collection() para crear una colección.

Utilice MilvusClientV2 para conectarse al servidor Milvus y createCollection() para crear una colección.

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);

Paso 2: Insertar entidades generadas aleatoriamente

Utilice insert() para insertar entidades en la colección.

Utilice insert() para insertar entidades en la colección.

# 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

Búsqueda con iterador

Los iteradores hacen que las búsquedas por similitud sean más escalables.

Para buscar con un iterador, llama al método search_iterator():

Para buscar con un iterador, llame al método searchIterator():

  1. Inicialice el iterador de búsqueda para definir los parámetros de búsqueda y los campos de salida.

  2. Utilice el método next() dentro de un bucle para paginar los resultados de la búsqueda.

    • Si el método devuelve un array vacío, el bucle finaliza y no hay más páginas disponibles.

    • Todos los resultados llevan los campos de salida especificados.

  3. Llame manualmente al método close() para cerrar el iterador una vez que se hayan recuperado todos los datos.

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 Descripción
data Una lista de incrustaciones vectoriales.
Milvus busca las incrustaciones vectoriales más similares a las especificadas.
anns_field El nombre del campo vectorial en la colección actual.
batch_size El número de entidades a devolver cada vez que se llama a next() en el iterador actual.
El valor por defecto es 1000. Ajústelo a un valor adecuado para controlar el número de entidades a devolver por iteración.
param Los parámetros específicos de esta operación.
  • metric_type: El tipo de métrica aplicado a esta operación. Debe ser el mismo que el utilizado al indexar el campo vectorial especificado anteriormente. Los valores posibles son L2, IP, COSINE, JACCARD, HAMMING.
  • params: Parámetros adicionales. Para más detalles, consulte search_iterator().
output_fields Una lista de nombres de campo para incluir en cada entidad devuelta.
El valor por defecto es None. Si no se especifica, sólo se incluye el campo principal.
limit El número total de entidades que se devolverán.
El valor predeterminado es -1, lo que indica que se devolverán todas las entidades coincidentes.
Parámetro Descripción
withCollectionName Establece el nombre de la colección. El nombre de la colección no puede estar vacío ni ser nulo.
withVectorFieldName Establezca el nombre del campo del vector de destino. El nombre del campo no puede estar vacío ni ser nulo.
withVectors Defina los vectores de destino. Se permiten hasta 16384 vectores.
withBatchSize El número de entidades a devolver cada vez que se llama a next() en el iterador actual.
El valor por defecto es 1000. Establézcalo a un valor apropiado para controlar el número de entidades a devolver por iteración.
withParams Especifica los parámetros de búsqueda en formato JSON. Para más información, consulte searchIterator().

Consulta con un iterador

Para consultar con un iterador, llame al método query_iterator():

Para buscar con un iterador, llame al 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 Descripción
batch_size El número de entidades a devolver cada vez que se llama a next() en el iterador actual.
El valor por defecto es 1000. Establézcalo a un valor apropiado para controlar el número de entidades a devolver por iteración.
expr Una condición de filtrado escalar para filtrar las entidades coincidentes.
El valor predeterminado es None, lo que indica que se ignora el filtrado escalar. Para crear una condición de filtrado escalar, consulte Reglas de expresión booleana.
output_fields Una lista de nombres de campo para incluir en cada entidad devuelta.
El valor por defecto es Ninguno. Si no se especifica, sólo se incluye el campo principal.
limit El número total de entidades que se devolverán.
El valor predeterminado es -1, lo que indica que se devolverán todas las entidades coincidentes.
Parámetro Descripción
withCollectionName Establece el nombre de la colección. El nombre de la colección no puede estar vacío ni ser nulo.
withExpr Establezca la expresión para consultar las entidades. Para crear una condición de filtrado escalar, consulte Reglas de expresión booleana.
withBatchSize El número de entidades a devolver cada vez que se llama a next() en el iterador actual.
El valor por defecto es 1000. Establézcalo a un valor apropiado para controlar el número de entidades a devolver por iteración.
addOutField Especifica un campo escalar de salida (Opcional).

Traducido porDeepLogo

Try Managed Milvus for Free

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

Get Started
Feedback

¿Fue útil esta página?