Ricerca ibrida con StructArray

Utilizza questa pagina per combinare la ricerca vettoriale StructArray con altre ricerche vettoriali in un'unica richiesta di ricerca ibrida. La ricerca ibrida StructArray può produrre risultati a livello di entità o a livello di elemento, a seconda degli oggetti AnnSearchRequest che si combinano.

Questa pagina utilizza la raccolta tech_articles tratta da "Creare un campo StructArray". La raccolta presenta un campo vettoriale di primo livello denominato title_vector e un campo StructArray denominato chunks. Il sottocampo chunks[emb_list_vector] è indicizzato per la ricerca EmbeddingList, mentre chunks[emb] è indicizzato per la ricerca a livello di elemento.

Come si applica la ricerca ibrida a StructArray

AnnSearchRequest combinazioneAmbito dei candidati finaliComportamento del risultatoelement_scope
Campo vettoriale a livello di collezione + sottocampo EmbeddingList di StructArrayA livello di entitàI candidati finali sono identificati dalla chiave primaria.Da non utilizzare.
Campo vettoriale a livello di collezione + sottocampo a livello di elemento di StructArrayLivello entitàI risultati a livello di elemento vengono raggruppati in candidati a livello di entità prima del riordino ibrido.Configurazione opzionale di raggruppamento a livello di elemento StructArray AnnSearchRequest.
Più sottocampi a livello di elemento all’interno dello stesso campo StructArrayLivello dell’elementoI candidati finali sono identificati dalla chiave primaria più l'offset dell'elemento Struct.Non utilizzare.
Sottocampi a livello di elemento sotto diversi campi StructArrayLivello dell’entitàGli offset degli elementi non condividono l’identità, pertanto ogni AnnSearchRequest a livello di elemento di StructArray viene compresso prima della riclassificazione.Configurazione facoltativa di compressione per ogni AnnSearchRequest e a livello di elemento di StructArray.

Avviso

Utilizzare l'element_scope solo per configurare il raggruppamento per oggetti a livello di elemento StructArray AnnSearchRequest in una ricerca ibrida a livello di elemento non della stessa struttura. Non utilizzarlo per richieste EmbeddingList, richieste vettoriali a livello di raccolta o ricerche ibride a livello di elemento dello stesso StructArray.

Prima di iniziare

Preparare la collezione, i dati e gli indici prima di eseguire la ricerca ibrida.

RequisitiDettagli
Campo StructArrayLa raccolta contiene un campo StructArray, ad esempio chunks.
Sottocampi vettorialiUtilizzare sottocampi vettoriali separati per la ricerca EmbeddingList e la ricerca a livello di elemento.
Indicichunks[emb_list_vector] utilizza una metrica di tipo MAX_SIM*. chunks[emb] utilizza una metrica vettoriale regolare, come COSINE, IP o L2.
RerankerScegliere un sistema di riclassificazione ibrido come RRFRanker o un altro sistema di riclassificazione supportato dall'applicazione.

Per la configurazione dell’indice, consultare i campi StructArray dell’indice.

Eseguire una ricerca ibrida con una richiesta EmbeddingList

La ricerca EmbeddingList su un sottocampo vettoriale StructArray è a livello di entità nella ricerca ibrida. Si comporta come una richiesta di ricerca vettoriale a livello di entità e non restituisce un unico offset dell’elemento Struct corrispondente.

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

In questo esempio, entrambi gli oggetti ` AnnSearchRequest ` producono candidati a livello di entità. Il risultato finale è indicizzato in base alla chiave primaria dell’entità padre. Non aggiungere ` element_scope ` alla richiesta `EmbeddingList`.

Quando tutti gli oggetti ` AnnSearchRequest ` hanno come target sottocampi vettoriali a livello di elemento all’interno dello stesso campo `StructArray`, la ricerca ibrida può mantenere i candidati a livello di elemento tramite il riclassamento. Questa è l’unica modalità ibrida di `StructArray` in cui i risultati finali rimangono a livello di elemento.

L’esempio seguente presuppone che il campo StructArray chunks abbia due sottocampi vettoriali a livello di elemento, chunks[emb] e chunks[code_emb], ed entrambi utilizzino metriche vettoriali regolari.

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

Entrambi gli oggetti AnnSearchRequest effettuano la ricerca nei sottocampi vettoriali presenti in chunks. Lo stesso offset con base zero fa riferimento allo stesso elemento Struct, pertanto il sistema di riclassificazione ibrido può classificare direttamente i candidati a livello di elemento. Non impostare element_scope in questa modalità poiché non viene eseguito alcun raggruppamento a livello di entità.

Se una ricerca ibrida combina un’ AnnSearchRequest a livello di elemento StructArray con una richiesta vettoriale a livello di collezione, una richiesta EmbeddingList o una richiesta a livello di elemento in un campo StructArray diverso, l’ambito finale dei candidati è a livello di entità. In questo caso, ogni AnnSearchRequest a livello di elemento StructArray viene raggruppata in candidati a livello di entità prima del riordino ibrido.

Utilizzare ` element_scope ` all’interno di ` params ` dell’ AnnSearchRequest a livello di elemento StructArray quando è necessario controllare il modo in cui vengono raggruppati più elementi corrispondenti provenienti dalla stessa entità.

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

In questo esempio, ` title_req ` è a livello di entità, quindi anche il risultato ibrido finale è a livello di entità. La richiesta ` chunk_req ` restituisce innanzitutto i risultati a livello di elemento da ` chunks[emb]`, quindi raggruppa gli elementi restituiti provenienti dalla stessa entità sommando i punteggi dei tre migliori elementi. Se ` element_scope ` viene omesso quando è necessario un raggruppamento a livello di entità, la strategia di raggruppamento predefinita è ` max`.

Scegliere una strategia di raggruppamento

StrategiaComportamentotopkRequisiti metrici
maxMantenere il punteggio migliore dell’elemento restituito per l’entità.Non consentito.Qualsiasi metrica vettoriale regolare supportata.
sumSommare tutti i punteggi degli elementi restituiti per l'entità.Non consentito.Solo metriche a correlazione positiva, come IP o COSINE.
avgCalcola la media di tutti i punteggi degli elementi restituiti per l’entità.Non consentito.Qualsiasi metrica vettoriale regolare supportata.
topk_sumSomma i migliori punteggi degli elementi restituiti da K per l'entità.Obbligatorio e deve essere positivo.Solo metriche a correlazione positiva, come IP o COSINE.
topk_avgCalcola la media dei punteggi degli elementi migliori restituiti dall'K per l'entità.Obbligatorio e deve essere positivo.Qualsiasi metrica vettoriale regolare supportata.

Il collasso utilizza solo i risultati degli elementi restituiti da quell'AnnSearchRequest a livello di elemento StructArray. Non esegue la scansione di ogni elemento Struct nell'entità dopo la ricerca ANN. Impostare l'limit della richiesta a un valore sufficientemente alto da fornire gli elementi che si desidera siano disponibili per il collasso.

Aggiungere filtri, ricerca per intervallo e raggruppamento

È possibile associare un’ element_filter a un AnnSearchRequest a livello di elemento di StructArray quando le condizioni scalari devono essere applicate agli stessi elementi Struct che partecipano alla ricerca vettoriale. È inoltre possibile utilizzare un filter di primo livello su hybrid_search() per le condizioni relative all’entità padre.

I campi vettoriali a livello di elemento di StructArray supportano la ricerca per intervallo nella ricerca ibrida. Aggiungere radius e, facoltativamente, range_filter all’ AnnSearchRequest a livello di elemento. Le richieste StructArray a livello di EmbeddingList non supportano la ricerca per intervallo.

Il raggruppamento ibrido a livello di elemento è supportato solo quando tutti gli oggetti ` AnnSearchRequest ` hanno come destinazione campi vettoriali a livello di elemento all’interno dello stesso campo `StructArray`, e ` group_by_field ` deve essere la chiave primaria. Il raggruppamento ibrido non è supportato quando la richiesta combina campi vettoriali a livello di collezione, campi `StructArray` diversi o richieste a livello di `EmbeddingList`. Non combinare la ricerca per intervallo con il raggruppamento.

Interpretazione dei risultati ibridi

Ambito dei candidati finaliChiave del risultatoComportamento dell’offsetQuando si verifica
A livello di entitàChiave primaria.Nessun offset degli elementi nel risultato finale.La richiesta ibrida include un campo vettoriale a livello di collezione, una richiesta EmbeddingList o richieste a livello di elemento in diversi campi StructArray.
A livello di elementoChiave primaria più campo StructArray padre più offset dell’elemento.L'offset dell'elemento selezionato può essere restituito quando esposto dall'API o dall'SDK.Tutti gli oggetti " AnnSearchRequest " sono a livello di elemento e si trovano all'interno dello stesso campo StructArray.

Limitazioni

  • Utilizzare element_scope solo per oggetti " AnnSearchRequest " a livello di elemento di StructArray che devono essere ridotti a candidati a livello di entità nella ricerca ibrida.

  • Non utilizzare element_scope per le richieste EmbeddingList, le richieste vettoriali a livello di raccolta o la ricerca ibrida a livello di elemento dello stesso StructArray.

  • sum e le strategie di raggruppamento topk_sum richiedono metriche di correlazione positiva, come IP o COSINE. Non utilizzarle con L2.

  • topk_sum e topk_avg richiedono un valore positivo di topk. Altre strategie di raggruppamento non devono includere topk.

  • Le richieste StructArray a livello di EmbeddingList non supportano la ricerca per intervallo né il raggruppamento.

  • Il raggruppamento ibrido è supportato solo per la ricerca ibrida a livello di elemento dello stesso StructArray e solo tramite chiave primaria.

  • Non combinare la ricerca per intervallo con il raggruppamento.

Errori comuni

  • Aggiunta di ` element_scope ` a una richiesta ibrida a livello di elemento dello stesso `StructArray`. Tale richiesta rimane a livello di elemento e non esegue il raggruppamento a livello di entità.

  • Aggiunta di un’ element_scope a un’ chunks[emb_list_vector]. La ricerca EmbeddingList è già a livello di entità.

  • Presupporre che due campi StructArray condividano gli offset degli elementi. L’ 3 con offset in chunks e l’ 3 con offset in un altro campo StructArray sono elementi diversi, quindi la richiesta ibrida diventa a livello di entità.

  • Utilizzo di topk_sum con L2. Utilizzare max, avg o topk_avg per metriche di distanza negative.

  • Ci si aspetta che i risultati ibridi a livello di entità includano l’offset dell’elemento Struct selezionato dopo il collasso.

Prossimi passi

  1. Per conoscere le due modalità di ricerca vettoriale di base con StructArray, leggere Ricerca vettoriale di base con StructArray.

  2. Per aggiungere filtri scalari alla ricerca ibrida, consultare Ricerca filtrata con StructArray.

  3. Per utilizzare i limiti di punteggio o di distanza nella ricerca ibrida, leggere Ricerca per intervallo con StructArray.

  4. Per raggruppare i risultati ibridi a livello di elemento per entità padre, leggere Ricerca raggruppata con StructArray.

  5. Per verificare i limiti di ricerca di StructArray, leggi " Limiti di StructArray".