Agrupación de resultados de búsqueda con StructArray

Utiliza esta página para agrupar los resultados de búsqueda a nivel de elemento de StructArray por entidad principal. La búsqueda a nivel de elemento puede devolver varios resultados de la misma entidad cuando varios elementos de Struct coinciden con la consulta. La agrupación agrupa esos resultados de elementos de modo que cada entidad principal aparezca como máximo una vez.

Esta página utiliza la colección « tech_articles » de «Crear un campo StructArray». La colección tiene un campo StructArray denominado « chunks ». El subcampo vectorial « chunks[emb] » está indexado para la búsqueda a nivel de elemento con una métrica vectorial regular.

Cómo se aplica la agrupación a StructArray

Modo de búsquedaComportamiento de la agrupaciónComportamiento de los resultados
Búsqueda en EmbeddingListNo es compatible.No aplicable.
Búsqueda a nivel de elementoCompatible mediante agrupación por clave primaria.Devuelve como máximo un resultado por entidad principal. Se conservan los metadatos a nivel de elemento, por lo que se puede devolver el índice o el desplazamiento del elemento seleccionado cuando lo exponga la API o el SDK.
Búsqueda híbridaSolo es compatible cuando todas las subbúsquedas se dirigen a campos vectoriales a nivel de elemento dentro del mismo campo StructArray.Las subbúsquedas a nivel de elemento se agrupan por clave primaria antes del procesamiento final de los resultados.

Utiliza la agrupación cuando la búsqueda a nivel de elemento sin agrupar devuelva demasiadas entidades principales duplicadas. Si deseas que cada elemento Struct coincidente aparezca como un resultado individual, utiliza la búsqueda vectorial básica con StructArray sin la opción « group_by_field ».

Antes de empezar

Prepara la colección, los datos y los índices antes de ejecutar la búsqueda agrupada.

RequisitosDetalles
Subcampo vectorial a nivel de elementoUtilice un subcampo vectorial StructArray, como chunks[emb], indexado con una métrica vectorial regular.
Consulta vectorial normalUtilice un vector de consulta regular, no un ` EmbeddingList`.
Agrupación por clave primariaUtilice la clave primaria de la colección como ` group_by_field`, por ejemplo, ` doc_id`.
Sin parámetros de rangoNo combine la búsqueda por agrupación con parámetros de búsqueda por rango, como radius o range_filter.

Para la configuración del índice, consulta «Campos StructArray del índice».

El siguiente ejemplo busca primero en fragmentos individuales y, a continuación, agrupa los resultados de los elementos según la clave primaria de la entidad principal.

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"],
        )

Sin agrupación, el mismo doc_id puede aparecer varias veces si varios fragmentos coinciden con la consulta. Con group_by_field="doc_id", cada entidad principal aparece como máximo una vez. La agrupación conserva los metadatos a nivel de elemento, por lo que el resultado agrupado puede seguir incluyendo el índice o el desplazamiento del elemento Struct seleccionado cuando la API o el SDK lo expongan.

Añadir filtros escalares

Puedes combinar la búsqueda agrupada con el filtrado escalar de StructArray. Utiliza « element_filter » cuando la condición escalar deba restringir qué elementos Struct participan en la búsqueda vectorial a nivel de elemento.

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]",
    ],
)

El predicado de nivel superior selecciona las entidades candidatas. El predicado « element_filter » restringe la búsqueda vectorial a nivel de elemento a los elementos de Struct que coincidan. A continuación, la agrupación agrupa los resultados de elementos coincidentes por la clave principal.

La agrupación híbrida con StructArray es una característica a nivel de elemento. Solo es compatible cuando todas las subbúsquedas se dirigen a campos vectoriales a nivel de elemento dentro del mismo campo StructArray. No utilices solicitudes a nivel de EmbeddingList en una búsqueda híbrida agrupada de StructArray.

El siguiente ejemplo parte de la base de que el campo StructArray « chunks » tiene dos subcampos vectoriales a nivel de elemento, « chunks[emb] » y « chunks[code_emb] », y que ambos están indexados con métricas vectoriales normales.

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]",
    ],
)

En este ejemplo, ambas subconsultas se dirigen a campos vectoriales a nivel de elemento dentro del mismo campo StructArray, chunks. Una búsqueda híbrida no admite la agrupación a nivel de elemento si mezcla campos vectoriales normales, diferentes campos StructArray o consultas a nivel de EmbeddingList.

Interpretar los resultados agrupados

Elemento del resultadoSignificado
idClave primaria de la entidad principal agrupada.
distance o puntuaciónPuntuación o distancia del elemento Struct seleccionado para esa entidad principal.
offsetPosición, contada a partir de cero, del elemento Struct seleccionado al devolverse.
Claves primarias repetidasNo se esperan al agrupar por la clave primaria.
limitSe aplica a los resultados agrupados de la entidad principal.

Limitaciones

  • La búsqueda por agrupación solo se aplica a la búsqueda vectorial de StructArray a nivel de elemento. La búsqueda de EmbeddingList y la búsqueda híbrida a nivel de EmbeddingList no admiten la agrupación.

  • Utiliza la clave primaria como « group_by_field ». La agrupación a nivel de elemento de StructArray no es una agrupación de uso general sobre campos escalares arbitrarios.

  • No combine la búsqueda por agrupación con la búsqueda por rango.

  • No utilices una consulta « EmbeddingList » ni una métrica « MAX_SIM* » para la búsqueda agrupada.

  • La agrupación híbrida solo es compatible cuando todas las subbúsquedas se dirigen a campos vectoriales a nivel de elemento dentro del mismo campo StructArray.

  • La agrupación híbrida no es compatible cuando la búsqueda híbrida combina un campo vectorial normal, un campo StructArray diferente o una solicitud a nivel de EmbeddingList.

Errores comunes

  • Utilizar la agrupación con ` chunks[emb_list_vector]`, que está pensada para la búsqueda en `EmbeddingList`.

  • Agrupación por un campo escalar que no sea la clave principal.

  • Agrupación por varios campos. La agrupación de StructArray a nivel de elemento solo admite la agrupación por clave primaria.

  • Esperar que los resultados agrupados representen todos los elementos Struct coincidentes. La agrupación devuelve como máximo un resultado por entidad principal.

  • Suponer que la búsqueda agrupada a nivel de elemento vuelve a calcular una puntuación de tipo « MAX_SIM* » al estilo de EmbeddingList. La agrupación agrupa los resultados a nivel de elemento; no cambia el modelo de puntuación.

  • Combinación de « group_by_field » con « radius » o « range_filter ».

Próximos pasos

  1. Para aprender primero la búsqueda a nivel de elemento sin agrupar, lee «Búsqueda vectorial básica con StructArray».

  2. Para añadir filtros escalares a la búsqueda agrupada, lee «Búsqueda filtrada con StructArray».

  3. Para utilizar límites de puntuación o distancia en lugar de agrupaciones, consulta «Búsqueda por rango con StructArray».

  4. Para consultar los límites de búsqueda de StructArray, lee «Límites de StructArray».