Búsqueda híbrida con StructArray

Utiliza esta página para combinar la búsqueda vectorial de StructArray con otras búsquedas vectoriales en una única solicitud de búsqueda híbrida. La búsqueda híbrida de StructArray puede generar resultados a nivel de entidad o a nivel de elemento, dependiendo de los objetos de AnnSearchRequest que se combinen.

Esta página utiliza la colección « tech_articles » de «Crear un campo StructArray». La colección tiene un campo vectorial de nivel superior denominado « title_vector » y un campo StructArray denominado « chunks ». El subcampo « chunks[emb_list_vector] » está indexado para la búsqueda EmbeddingList, y « chunks[emb] » está indexado para la búsqueda a nivel de elemento.

Cómo se aplica la búsqueda híbrida a StructArray

AnnSearchRequest combinaciónÁmbito de candidatos finalComportamiento del resultadoelement_scope
Campo vectorial a nivel de colección + subcampo «EmbeddingList» de StructArrayNivel de entidadLos candidatos finales se identifican mediante la clave primaria.No utilizar.
Campo vectorial a nivel de colección + subcampo a nivel de elemento de StructArrayNivel de entidadLos resultados a nivel de elemento se agrupan en candidatos a nivel de entidad antes de la reordenación híbrida.Configuración opcional de agrupación en el campo de nivel de elemento de StructArray AnnSearchRequest.
Varios subcampos a nivel de elemento bajo el mismo campo StructArrayNivel de elementoLos candidatos finales se identifican mediante la clave primaria más el desplazamiento del elemento Struct.No utilizar.
Subcampos a nivel de elemento bajo diferentes campos StructArrayNivel de entidadLos desplazamientos de los elementos no comparten identidad, por lo que cada AnnSearchRequest a nivel de elemento de StructArray se colapsa antes de volver a clasificar.Configuración opcional de colapso en cada « AnnSearchRequest » a nivel de elemento de StructArray.

Advertencia

Utiliza « element_scope » únicamente para configurar el colapso de objetos de nivel de elemento de StructArray AnnSearchRequest en una búsqueda híbrida a nivel de elemento que no sea de la misma estructura. No lo utilices para solicitudes de EmbeddingList, solicitudes vectoriales a nivel de colección ni búsquedas híbridas a nivel de elemento de la misma StructArray.

Antes de empezar

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

RequisitosDetalles
Campo StructArrayLa colección contiene un campo StructArray, como chunks.
Subcampos vectorialesUtilice subcampos vectoriales independientes para la búsqueda en EmbeddingList y la búsqueda a nivel de elemento.
Índiceschunks[emb_list_vector] utiliza una métrica de tipo « MAX_SIM* ». « chunks[emb] » utiliza una métrica vectorial estándar, como « COSINE », « IP » o « L2 ».
ReordenadorElige un reordenador híbrido, como RRFRanker u otro reordenador compatible con tu aplicación.

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

Ejecutar una búsqueda híbrida con una solicitud EmbeddingList

La búsqueda con EmbeddingList en un subcampo vectorial de StructArray se realiza a nivel de entidad en la búsqueda híbrida. Se comporta como una solicitud de búsqueda vectorial a nivel de entidad y no devuelve un único desplazamiento de elemento Struct coincidente.

from pymilvus import AnnSearchRequest, MilvusClient, RRFRanker
from pymilvus.client.embedding_list import EmbeddingList

client = MilvusClient(
    uri="http://localhost:19530",
    token="root:Milvus",
)

query_vector = [0.19, 0.24, 0.30, 0.37]

query_list = EmbeddingList()
query_list.add([0.12, 0.21, 0.32, 0.44])
query_list.add([0.18, 0.23, 0.29, 0.36])

title_req = AnnSearchRequest(
    data=[query_vector],
    anns_field="title_vector",
    limit=10,
)

chunk_list_req = AnnSearchRequest(
    data=[query_list],
    anns_field="chunks[emb_list_vector]",
    limit=10,
)

results = client.hybrid_search(
    collection_name="tech_articles",
    reqs=[title_req, chunk_list_req],
    ranker=RRFRanker(),
    limit=5,
    output_fields=[
        "doc_id",
        "title",
        "category",
        "chunks[text]",
        "chunks[section]",
    ],
)

En este ejemplo, ambos objetos ` AnnSearchRequest ` generan candidatos a nivel de entidad. El resultado final se indexa mediante la clave primaria de la entidad principal. No añadas ` element_scope ` a la solicitud `EmbeddingList`.

Cuando todos los objetos ` AnnSearchRequest ` se dirigen a subcampos vectoriales a nivel de elemento dentro del mismo campo `StructArray`, la búsqueda híbrida puede conservar los candidatos a nivel de elemento mediante una nueva clasificación. Este es el único modo híbrido de `StructArray` en el que los resultados finales se mantienen a nivel de elemento.

El siguiente ejemplo supone que el campo StructArray de chunks tiene dos subcampos vectoriales a nivel de elemento, chunks[emb] y chunks[code_emb], y que ambos utilizan métricas vectoriales normales.

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,
    output_fields=[
        "doc_id",
        "title",
        "chunks[text]",
        "chunks[section]",
        "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"],
        )

Ambos objetos « AnnSearchRequest » buscan subcampos vectoriales en « chunks ». El mismo desplazamiento con base en cero hace referencia al mismo elemento de Struct, por lo que el reordenador híbrido puede clasificar directamente los candidatos a nivel de elemento. No establezcas « element_scope » en este modo, ya que no se realiza ninguna agrupación a nivel de entidad.

Si una búsqueda híbrida combina un « AnnSearchRequest » a nivel de elemento de StructArray con una solicitud vectorial a nivel de colección, una solicitud «EmbeddingList» o una solicitud a nivel de elemento en un campo diferente de StructArray, el ámbito final de los candidatos es a nivel de entidad. En este caso, cada « AnnSearchRequest » a nivel de elemento de StructArray se agrupa en candidatos a nivel de entidad antes de la reordenación híbrida.

Utiliza « element_scope » dentro de « params » del « AnnSearchRequest » a nivel de elemento de StructArray cuando necesites controlar cómo se agrupan varios elementos coincidentes de la misma entidad.

title_req = AnnSearchRequest(
    data=[query_vector],
    anns_field="title_vector",
    limit=10,
)

chunk_req = AnnSearchRequest(
    data=[query_vector],
    anns_field="chunks[emb]",
    param={
        "params": {
            "element_scope": {
                "collapse": {
                    "strategy": "topk_sum",
                    "topk": 3,
                },
            },
        },
    },
    limit=30,
    expr='element_filter(chunks, $[quality_score] > 0.8)',
)

results = client.hybrid_search(
    collection_name="tech_articles",
    reqs=[title_req, chunk_req],
    ranker=RRFRanker(),
    limit=5,
    output_fields=[
        "doc_id",
        "title",
        "category",
        "chunks[text]",
        "chunks[section]",
        "chunks[quality_score]",
    ],
)

En este ejemplo, « title_req » es a nivel de entidad, por lo que el resultado híbrido final también es a nivel de entidad. La solicitud « chunk_req » devuelve primero los resultados de los elementos de « chunks[emb] » y, a continuación, agrupa los elementos devueltos de la misma entidad sumando las tres mejores puntuaciones de los elementos. Si se omite « element_scope » cuando se necesita una agrupación a nivel de entidad, la estrategia de agrupación por defecto es « max ».

Elegir una estrategia de agrupación

EstrategiaComportamientotopkRequisito de métrica
maxConservar la mejor puntuación del elemento devuelto para la entidad.No permitido.Cualquier métrica vectorial regular compatible.
sumSuma todas las puntuaciones de los elementos devueltos para la entidad.No permitido.Solo métricas de correlación positiva, como IP o COSINE.
avgCalcular la media de todas las puntuaciones de los elementos devueltos para la entidad.No permitido.Cualquier métrica vectorial regular admitida.
topk_sumSuma las mejores puntuaciones de los elementos devueltos por « K » para la entidad.Es obligatorio y debe ser positivo.Solo métricas de correlación positiva, como « IP » o « COSINE ».
topk_avgCalcular la media de las mejores puntuaciones de los elementos devueltos por « K » para la entidad.Es obligatorio y debe ser positivo.Cualquier métrica vectorial regular compatible.

La función «Collapse» utiliza únicamente los resultados de los elementos devueltos por ese « AnnSearchRequest » a nivel de elemento de StructArray. No analiza todos los elementos de Struct de la entidad tras la búsqueda ANN. Establece el valor de « limit » de la solicitud lo suficientemente alto como para proporcionar los elementos que deseas que estén disponibles para la función «Collapse».

Añadir filtros, búsqueda por rango y agrupación

Puede asociar un « element_filter » a un « AnnSearchRequest » a nivel de elemento de StructArray cuando deban aplicarse condiciones escalares a los mismos elementos de Struct que participan en la búsqueda vectorial. También puede utilizar un « filter » de nivel superior en « hybrid_search() » para condiciones de la entidad principal.

Los campos vectoriales a nivel de elemento de StructArray admiten la búsqueda por rango en la búsqueda híbrida. Añade radius y, opcionalmente, range_filter a la AnnSearchRequest a nivel de elemento. Las solicitudes de StructArray a nivel de EmbeddingList no admiten la búsqueda por rango.

La agrupación híbrida a nivel de elemento solo es compatible cuando todos los objetos ` AnnSearchRequest ` se dirigen a campos vectoriales a nivel de elemento dentro del mismo campo `StructArray`, y ` group_by_field ` debe ser la clave principal. La agrupación híbrida no es compatible cuando la solicitud mezcla campos vectoriales a nivel de colección, diferentes campos `StructArray` o solicitudes a nivel de `EmbeddingList`. No combine la búsqueda por rango con la agrupación.

Interpretación de los resultados híbridos

Ámbito de candidatos finalClave del resultadoComportamiento del desplazamientoCuándo se produce
Nivel de entidadClave primaria.No hay desplazamiento de elementos en el resultado final.La solicitud híbrida incluye un campo vectorial a nivel de colección, una solicitud EmbeddingList o solicitudes a nivel de elemento en distintos campos StructArray.
Nivel de elementoClave primaria más el campo StructArray padre más el desplazamiento del elemento.El desplazamiento del elemento seleccionado puede devolverse cuando lo exponga la API o el SDK.Todos los objetos « AnnSearchRequest » son a nivel de elemento y se encuentran bajo el mismo campo «StructArray».

Limitaciones

  • Utiliza « element_scope » únicamente para objetos « AnnSearchRequest » a nivel de elemento de StructArray que deban reducirse a candidatos a nivel de entidad en la búsqueda híbrida.

  • No utilice « element_scope » para solicitudes de EmbeddingList, solicitudes vectoriales a nivel de colección ni búsquedas híbridas a nivel de elemento del mismo StructArray.

  • sum Las estrategias de reducción « topk_sum » y «and» requieren métricas de correlación positiva, como « IP » o « COSINE ». No las utilices con « L2 ».

  • topk_sum y topk_avg requieren un valor positivo de topk. Las demás estrategias de colapso no deben incluir topk.

  • Las solicitudes de StructArray a nivel de EmbeddingList no admiten la búsqueda por rango ni la agrupación.

  • La agrupación híbrida solo es compatible con la búsqueda híbrida a nivel de elemento del mismo StructArray y únicamente mediante la clave primaria.

  • No se debe combinar la búsqueda por rango con la agrupación.

Errores comunes

  • Añadir « element_scope » a una solicitud híbrida a nivel de elemento del mismo StructArray. Dicha solicitud sigue siendo a nivel de elemento y no realiza la compresión a nivel de entidad.

  • Añadir « element_scope » a « chunks[emb_list_vector] ». La búsqueda de «EmbeddingList» ya se realiza a nivel de entidad.

  • Suponer que dos campos de StructArray comparten desplazamientos de elementos. El desplazamiento « 3 » en « chunks » y el desplazamiento « 3 » en otro campo de StructArray corresponden a elementos diferentes, por lo que la solicitud híbrida pasa a ser a nivel de entidad.

  • Utilizando topk_sum con L2. Utiliza max, avg o topk_avg para métricas de distancia negativas.

  • Se espera que los resultados híbridos a nivel de entidad incluyan el desplazamiento del elemento Struct seleccionado tras el colapso.

Próximos pasos

  1. Para conocer los dos modos básicos de búsqueda vectorial con StructArray, consulta «Búsqueda vectorial básica con StructArray».

  2. Para añadir filtros escalares a la búsqueda híbrida, consulta «Búsqueda filtrada con StructArray».

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

  4. Para agrupar los resultados híbridos a nivel de elemento por entidad principal, consulta «Búsqueda agrupada con StructArray».

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