Gruppierung von Suchergebnissen mit StructArray
Verwenden Sie diese Seite, um Suchergebnisse auf StructArray-Ebene nach der übergeordneten Entität zu gruppieren. Bei der Suche auf Elementebene können mehrere Treffer derselben Entität zurückgegeben werden, wenn mehrere Struct-Elemente der Abfrage entsprechen. Durch die Gruppierung werden diese Elementtreffer zusammengefasst, sodass jede übergeordnete Entität höchstens einmal erscheint.
Diese Seite verwendet die Sammlung „ tech_articles “ aus dem Abschnitt „Erstellen eines StructArray-Feldes“. Die Sammlung enthält ein StructArray-Feld namens „ chunks “. Das Vektor-Unterfeld „ chunks[emb] “ ist für die Suche auf Elementebene mit einer regulären Vektormetrik indiziert.
Wie die Gruppierung auf StructArray angewendet wird
| Suchmodus | Gruppierungsverhalten | Verhalten der Ergebnisse |
|---|---|---|
| „EmbeddingList“-Suche | Nicht unterstützt. | Nicht zutreffend. |
| Suche auf Elementebene | Wird durch Gruppierung nach dem Primärschlüssel unterstützt. | Liefert höchstens ein Ergebnis pro übergeordneter Entität. Metadaten auf Elementebene bleiben erhalten, sodass der Index oder Offset des ausgewählten Elements zurückgegeben werden kann, wenn dieser über die API oder das SDK bereitgestellt wird. |
| Hybride Suche | Wird nur unterstützt, wenn alle Teilsuchen auf Vektorfelder auf Elementebene unter demselben StructArray-Feld abzielen. | Teilsuchen auf Elementebene werden vor der endgültigen Ergebnisverarbeitung nach Primärschlüssel gruppiert. |
Verwenden Sie die Gruppierung, wenn eine nicht gruppierte Suche auf Elementebene zu viele doppelte übergeordnete Entitäten zurückgibt. Wenn Sie jedes übereinstimmende Struct-Element als einzelnen Treffer erhalten möchten, verwenden Sie die einfache Vektorsuche mit StructArray ohne „ group_by_field “.
Bevor Sie beginnen
Bereiten Sie die Sammlung, die Daten und die Indizes vor, bevor Sie die gruppierte Suche ausführen.
| Voraussetzung | Details |
|---|---|
| Vektor-Unterfeld auf Elementebene | Verwenden Sie ein StructArray-Vektor-Unterfeld wie beispielsweise „ chunks[emb] “, das mit einer regulären Vektormetrik indiziert ist. |
| Reguläre Vektorabfrage | Verwenden Sie einen regulären Abfragevektor, keinen „ EmbeddingList “. |
| Gruppierung nach Primärschlüssel | Verwenden Sie den Primärschlüssel der Sammlung als „ group_by_field “, z. B. „ doc_id “. |
| Keine Bereichsparameter | Kombinieren Sie die Gruppierungssuche nicht mit Bereichssuchparametern wie radius oder range_filter. |
Informationen zur Indexeinrichtung finden Sie unter „Index StructArray-Felder“.
Gruppierte Suche auf Elementebene ausführen
Im folgenden Beispiel werden zunächst einzelne Chunks durchsucht, anschließend werden die Elementtreffer anhand des Primärschlüssels der übergeordneten Entität gruppiert.
from pymilvus import MilvusClient
client = MilvusClient(
uri="http://localhost:19530",
token="root:Milvus",
)
query_vector = [0.19, 0.24, 0.30, 0.37]
results = client.search(
collection_name="tech_articles",
data=[query_vector],
anns_field="chunks[emb]",
limit=5,
group_by_field="doc_id",
output_fields=[
"doc_id",
"title",
"chunks[text]",
"chunks[section]",
"chunks[page]",
"chunks[quality_score]",
],
)
for hits in results:
for hit in hits:
print(
"doc_id:", hit["id"],
"distance:", hit["distance"],
"offset:", hit.get("offset"),
"entity:", hit["entity"],
)
Ohne Gruppierung kann dasselbe „ doc_id “ mehrfach erscheinen, wenn mehrere Chunks der Abfrage entsprechen. Mit „ group_by_field="doc_id" “ erscheint jede übergeordnete Entität höchstens einmal. Durch die Gruppierung bleiben Metadaten auf Elementebene erhalten, sodass das gruppierte Ergebnis weiterhin den ausgewählten Struct-Element-Index oder -Offset enthalten kann, sofern die API oder das SDK diesen bereitstellt.
Skalarfilter hinzufügen
Sie können die Gruppierungssuche mit der skalaren Filterung von `StructArray` kombinieren. Verwenden Sie ` element_filter `, wenn die skalare Bedingung einschränken soll, welche `Struct`-Elemente an der Vektorsuche auf Elementebene teilnehmen.
filter_expr = (
'category == "search" && '
'element_filter(chunks, '
'$[section] == "index" && '
'$[quality_score] > 0.9)'
)
results = client.search(
collection_name="tech_articles",
data=[query_vector],
anns_field="chunks[emb]",
filter=filter_expr,
limit=5,
group_by_field="doc_id",
output_fields=[
"doc_id",
"title",
"category",
"chunks[text]",
"chunks[section]",
"chunks[quality_score]",
],
)
Das Prädikat der obersten Ebene wählt Kandidatenentitäten aus. Das Prädikat „ element_filter “ beschränkt die Vektorsuche auf Elementebene auf übereinstimmende Struct-Elemente. Die Gruppierung fasst dann die übereinstimmenden Elementtreffer anhand des Primärschlüssels zusammen.
Verwenden Sie die Gruppierung bei der hybriden Suche
Die hybride Gruppierung mit „StructArray“ ist eine Funktion auf Elementebene. Sie wird nur unterstützt, wenn alle Teilsuchen auf Vektorfelder auf Elementebene unter demselben „StructArray“-Feld abzielen. Verwenden Sie keine Anfragen auf „EmbeddingList“-Ebene in einer gruppierten hybriden „StructArray“-Suche.
Das folgende Beispiel geht davon aus, dass das StructArray-Feld „ chunks “ zwei Vektor-Unterfelder auf Elementebene enthält, „ chunks[emb] “ und „ chunks[code_emb] “, und dass beide mit regulären Vektormetriken indiziert sind.
from pymilvus import AnnSearchRequest, RRFRanker
index_chunk_req = AnnSearchRequest(
data=[query_vector],
anns_field="chunks[emb]",
limit=10,
expr='element_filter(chunks, $[section] == "index")',
)
code_chunk_req = AnnSearchRequest(
data=[code_query_vector],
anns_field="chunks[code_emb]",
limit=10,
expr='element_filter(chunks, $[has_code] == true)',
)
results = client.hybrid_search(
collection_name="tech_articles",
reqs=[index_chunk_req, code_chunk_req],
ranker=RRFRanker(),
limit=5,
group_by_field="doc_id",
output_fields=[
"doc_id",
"title",
"chunks[text]",
"chunks[section]",
],
)
In diesem Beispiel zielen beide Unterabfragen auf Vektorfelder auf Elementebene unter demselben StructArray-Feld „ chunks “ ab. Eine Hybrid-Suche unterstützt keine Gruppierung auf Elementebene, wenn sie normale Vektorfelder, verschiedene StructArray-Felder oder Abfragen auf „EmbeddingList“-Ebene mischt.
Gruppierte Ergebnisse interpretieren
| Ergebniselement | Bedeutung |
|---|---|
id | Primärschlüssel der gruppierten übergeordneten Entität. |
distance oder Wert | Wert oder Abstand des ausgewählten Struct-Elements für diese übergeordnete Entität. |
offset | Nullbasierte Position des ausgewählten Struct-Elements bei der Rückgabe. |
| Wiederholte Primärschlüssel | Bei einer Gruppierung nach dem Primärschlüssel nicht zu erwarten. |
limit | Gilt für gruppierte Ergebnisse der übergeordneten Entität. |
Einschränkungen
Die Gruppierungssuche gilt nur für die StructArray-Vektorsuche auf Elementebene. Die EmbeddingList-Suche und die hybride Suche auf EmbeddingList-Ebene unterstützen keine Gruppierung.
Verwenden Sie den Primärschlüssel als „
group_by_field“. Die Gruppierung auf StructArray-Ebene ist keine universelle Gruppierung nach beliebigen Skalarfeldern.Kombinieren Sie die Gruppierungssuche nicht mit der Bereichssuche.
Verwenden Sie für die Gruppierungssuche keine „
EmbeddingList“-Abfrage oder eine „MAX_SIM*“-Metrik.Die hybride Gruppierung wird nur unterstützt, wenn alle Teilsuchen auf Vektorfelder auf Elementebene unter demselben StructArray-Feld abzielen.
Die hybride Gruppierung wird nicht unterstützt, wenn die hybride Suche ein normales Vektorfeld, ein anderes StructArray-Feld oder eine Abfrage auf EmbeddingList-Ebene einbezieht.
Häufige Fehler
Verwendung der Gruppierung mit „
chunks[emb_list_vector]“, das für die „EmbeddingList“-Suche vorgesehen ist.Gruppierung nach einem Skalarfeld, das kein Primärschlüssel ist.
Gruppierung nach mehreren Feldern. Die StructArray-Gruppierung auf Elementebene unterstützt nur die Gruppierung nach Primärschlüsseln.
Die Erwartung, dass gruppierte Ergebnisse jedes übereinstimmende Struct-Element darstellen. Die Gruppierung liefert höchstens ein Ergebnis pro übergeordneter Entität.
Annahme, dass die gruppierte Suche auf Elementebene einen „
MAX_SIM*“-Score im Stil von „EmbeddingList“ neu berechnet. Die Gruppierung fasst Treffer auf Elementebene zusammen; sie ändert das Bewertungsmodell nicht.Kombination von „
group_by_field“ mit „radius“ oder „range_filter“.
Nächste Schritte
Um zunächst die ungegruppierte Suche auf Elementebene kennenzulernen, lesen Sie „Grundlegende Vektorsuche mit StructArray“.
Um der gruppierten Suche skalare Filter hinzuzufügen, lesen Sie „Gefilterte Suche mit StructArray“.
Um anstelle der Gruppierung Score- oder Distanzgrenzen zu verwenden, lesen Sie „Bereichssuche mit StructArray“.
Um die Suchgrenzen von StructArray zu überprüfen, lesen Sie „StructArray-Grenzen“.