milvus-logo
LFAI
Home
  • Benutzerhandbuch

Mit Iteratoren

Milvus bietet Such- und Abfrage-Iteratoren für die Iteration durch ein großes Volumen von Entitäten. Da Milvus TopK auf 16384 begrenzt, können Benutzer Iteratoren verwenden, um große Zahlen oder sogar ganze Entitäten in einer Sammlung im Batch-Modus zurückzugeben.

Überblick

Iteratoren sind ein effizientes Werkzeug zum Scannen einer ganzen Sammlung oder zum Iterieren durch eine große Menge von Entitäten durch Angabe von Primärschlüsselwerten oder eines Filterausdrucks. Im Vergleich zu einem Such- oder Abfrageaufruf mit Offset- und Limit-Parametern ist die Verwendung von Iteratoren effizienter und skalierbarer.

Vorteile der Verwendung von Iteratoren

  • Vereinfachung: Die komplexen Offset- und Limit-Einstellungen entfallen.

  • Effizient: Ermöglicht einen skalierbaren Datenabruf, indem nur die benötigten Daten abgerufen werden.

  • Konsistenz: Gewährleistet eine konsistente Datensatzgröße mit booleschen Filtern.

Hinweise

  • Diese Funktion ist für Milvus 2.3.x oder höher verfügbar.

Vorbereitungen

Der folgende Vorbereitungsschritt stellt eine Verbindung zu Milvus her und fügt zufällig generierte Entitäten in eine Sammlung ein.

Schritt 1: Erstellen einer Sammlung

Verwenden Sie MilvusClient um sich mit dem Milvus-Server zu verbinden und create_collection() um eine Sammlung zu erstellen.

Verwenden Sie MilvusClientV2 um eine Verbindung zum Milvus-Server herzustellen und createCollection() um eine Sammlung zu erstellen.

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

Schritt 2: Zufällig generierte Entitäten einfügen

Verwenden Sie insert() um Entitäten in die Sammlung einzufügen.

Verwenden Sie insert() um Entitäten in die Sammlung einzufügen.

# 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

Suche mit Iterator

Iteratoren machen Ähnlichkeitssuchen besser skalierbar.

Um mit einem Iterator zu suchen, rufen Sie die Methode search_iterator() auf:

Um mit einem Iterator zu suchen, rufen Sie die Methode searchIterator() auf:

  1. Initialisieren Sie den Such-Iterator, um die Suchparameter und Ausgabefelder zu definieren.

  2. Verwenden Sie die next() -Methode innerhalb einer Schleife, um durch die Suchergebnisse zu paginieren.

    • Wenn die Methode ein leeres Array zurückgibt, endet die Schleife, und es sind keine weiteren Seiten verfügbar.

    • Alle Ergebnisse enthalten die angegebenen Ausgabefelder.

  3. Rufen Sie manuell die Methode close() auf, um den Iterator zu schließen, sobald alle Daten abgerufen wurden.

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
Parameter Beschreibung
data Eine Liste von Vektoreinbettungen.
Milvus sucht nach den Vektoreinbettungen, die den angegebenen am ähnlichsten sind.
anns_field Der Name des Vektorfeldes in der aktuellen Sammlung.
batch_size Die Anzahl der Entitäten, die jedes Mal zurückgegeben werden sollen, wenn Sie next() für den aktuellen Iterator aufrufen.
Der Wert ist standardmäßig 1000. Setzen Sie ihn auf einen geeigneten Wert, um die Anzahl der pro Iteration zurückzugebenden Objekte zu steuern.
param Die spezifischen Parametereinstellungen für diese Operation.
  • metric_type: Der Metrik-Typ, der auf diese Operation angewendet wird. Dies sollte derselbe sein, der verwendet wird, wenn Sie das oben angegebene Vektorfeld indizieren. Mögliche Werte sind L2, IP, COSINE, JACCARD, HAMMING.
  • params: Zusätzliche Parameter. Einzelheiten finden Sie unter search_iterator().
output_fields Eine Liste von Feldnamen, die in jeder zurückgegebenen Entität enthalten sein sollen.
Der Standardwert ist None. Wenn er nicht angegeben wird, wird nur das Primärfeld einbezogen.
limit Die Gesamtzahl der zurückzugebenden Entitäten.
Der Standardwert ist -1, was bedeutet, dass alle passenden Entitäten zurückgegeben werden.
Parameter Beschreibung
withCollectionName Legt den Namen der Sammlung fest. Der Sammlungsname darf nicht leer oder null sein.
withVectorFieldName Zielvektorfeld nach Name festlegen. Der Feldname darf nicht leer oder ungültig sein.
withVectors Legen Sie die Zielvektoren fest. Bis zu 16384 Vektoren sind zulässig.
withBatchSize Die Anzahl der Entitäten, die bei jedem Aufruf von next() für den aktuellen Iterator zurückgegeben werden.
Der Standardwert ist 1000. Setzen Sie ihn auf einen geeigneten Wert, um die Anzahl der Entitäten zu steuern, die pro Iteration zurückgegeben werden.
withParams Gibt die Parameter der Suche im JSON-Format an. Weitere Informationen finden Sie unter searchIterator().

Abfrage mit einem Iterator

Um mit einem Iterator abzufragen, rufen Sie die Methode query_iterator() auf:

Um mit einem Iterator zu suchen, rufen Sie die Methode queryIterator() auf:

# 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]
// ]

Parameter Beschreibung
batch_size Die Anzahl der Entitäten, die jedes Mal zurückgegeben werden sollen, wenn Sie next() für den aktuellen Iterator aufrufen.
Der Standardwert ist 1000. Setzen Sie ihn auf einen geeigneten Wert, um die Anzahl der Entitäten zu steuern, die pro Iteration zurückgegeben werden sollen.
expr Eine skalare Filterbedingung, um übereinstimmende Entitäten zu filtern.
Der Standardwert ist None, was anzeigt, dass die skalare Filterung ignoriert wird. Um eine skalare Filterbedingung zu erstellen, siehe Boolesche Ausdrucksregeln.
output_fields Eine Liste von Feldnamen, die in jeder zurückgegebenen Entität enthalten sein sollen.
Der Standardwert ist None. Wenn er nicht angegeben wird, wird nur das Primärfeld einbezogen.
limit Die Gesamtzahl der zurückzugebenden Entitäten.
Der Standardwert ist -1, was bedeutet, dass alle passenden Entitäten zurückgegeben werden.
Parameter Beschreibung
withCollectionName Legt den Namen der Sammlung fest. Der Sammlungsname darf nicht leer oder null sein.
withExpr Legen Sie den Ausdruck für die Abfrage von Entitäten fest. Um eine skalare Filterbedingung zu erstellen, siehe Boolesche Ausdrucksregeln.
withBatchSize Die Anzahl der Entitäten, die bei jedem Aufruf von next() für den aktuellen Iterator zurückgegeben werden sollen.
Der Standardwert ist 1000. Setzen Sie ihn auf einen geeigneten Wert, um die Anzahl der pro Iteration zurückzugebenden Entitäten zu steuern.
addOutField Gibt ein skalares Ausgabefeld an (Optional).

Übersetzt vonDeepLogo

Try Managed Milvus for Free

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

Get Started
Feedback

War diese Seite hilfreich?