Ricerca per intervallo con StructArray

Utilizzare questa pagina per eseguire una ricerca per intervallo sui sottocampi vettoriali di StructArray. La ricerca per intervallo restituisce i risultati vettoriali il cui punteggio o distanza rientra in un intervallo specificato. Per i campi StructArray, utilizzare la ricerca per intervallo con la ricerca vettoriale a livello di elemento, in cui ogni elemento Struct viene cercato in modo indipendente.

Questa pagina utilizza la raccolta " tech_articles " ( Creazione di un campo StructArray). La raccolta presenta un campo StructArray denominato " chunks". Il sottocampo vettoriale " chunks[emb] " è indicizzato per la ricerca a livello di elemento con una metrica vettoriale regolare, come " COSINE", " IP" o " L2".

Come si applica la ricerca per intervallo a StructArray

Modalità di ricercaComportamento della ricerca per intervalloGranularità dei risultati
Ricerca EmbeddingListNon supportata.Non applicabile.
Ricerca a livello di elementoUtilizzare una query vettoriale standard con l'radius e, facoltativamente, l'range_filter.Livello degli elementi della struttura.
Ricerca ibridaSupportata quando la richiesta StructArray ha come obiettivo un campo vettoriale a livello di elemento. Le richieste a livello di EmbeddingList non supportano la ricerca per intervallo.Ricerca secondaria a livello di elemento, seguita da un nuovo ordinamento ibrido.

Se sono necessari solo gli elementi Struct più vicini, iniziare con la ricerca vettoriale di base con StructArray. Utilizzare la ricerca per intervallo quando il risultato deve soddisfare un limite di punteggio o di distanza anziché solo una classifica top-K.

Prima di iniziare

Preparare la raccolta, i dati e gli indici prima di eseguire la ricerca per intervallo.

RequisitiDettagli
Campo StructArrayLa collezione contiene un campo StructArray, ad esempio chunks.
Sottocampo vettoriale a livello di elementoIl sottocampo vettoriale di destinazione è chunks[emb], non chunks[emb_list_vector].
Metrica di indicizzazioneIl sottocampo vettoriale è indicizzato con una metrica vettoriale regolare, come COSINE, IP o L2.
Dati della queryLa query è un vettore regolare, non un EmbeddingList.

Per la configurazione dell’indice, consultare Campi StructArray dell’indice.

Utilizzare radius e range_filter

Impostare ` radius ` per definire il limite di ricerca. Impostare ` range_filter ` quando è necessario anche un limite interno. La direzione dipende dal fatto che sia preferibile una distanza minore o un punteggio di similarità maggiore.

Tipo di metricaÈ preferibile un punteggio più alto?Condizione di intervallo quando si utilizza ` range_filter `
L2No. È preferibile una distanza minore.range_filter <= distance < radius
IP, COSINESì. Un punteggio più alto è migliore.radius < distance <= range_filter

Quando è impostato solo " radius ", la ricerca per intervallo restituisce i risultati che soddisfano il limite esterno della metrica. Scegli i valori in base alla scala di punteggio o di distanza dei tuoi embedding.

L'esempio seguente ricerca singoli blocchi i cui vettori di " chunks[emb] " siano sufficientemente simili al vettore di query. Ogni risultato trovato rappresenta un elemento Struct corrispondente.

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]",
    search_params={
        "params": {
            "radius": 0.80,
            "range_filter": 0.95,
        },
    },
    limit=10,
    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"],
        )

In questo esempio, ` COSINE ` è una metrica di tipo "similarity", quindi l'intervallo dei risultati è maggiore di ` radius ` e minore o uguale a ` range_filter`. Il valore ` offset ` identifica l'elemento Struct corrispondente nell'array ` chunks ` quando viene restituito.

Aggiungere filtri scalari

È possibile combinare la ricerca per intervallo a livello di elemento con il filtraggio scalare di StructArray. Utilizzare un predicato di primo livello per i campi dell’entità padre e utilizzare element_filter per limitare quali elementi Struct partecipano alla ricerca per intervallo vettoriale.

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]",
    search_params={
        "params": {
            "radius": 0.80,
            "range_filter": 0.95,
        },
    },
    filter=filter_expr,
    limit=10,
    output_fields=[
        "doc_id",
        "title",
        "category",
        "chunks[text]",
        "chunks[section]",
        "chunks[quality_score]",
    ],
)

Il predicato di primo livello seleziona le entità candidate. Il predicato ` element_filter ` limita la ricerca per intervallo vettoriale agli elementi Struct corrispondenti. Per ulteriori esempi di filtraggio, vedere Ricerca filtrata con StructArray.

I campi vettoriali a livello di elemento di StructArray supportano la ricerca per intervallo nella ricerca ibrida. Aggiungere ` radius ` e, facoltativamente, ` range_filter ` alla richiesta ` AnnSearchRequest ` che ha come destinazione il campo vettoriale a livello di elemento di StructArray.

from pymilvus import AnnSearchRequest, RRFRanker

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

chunk_req = AnnSearchRequest(
    data=[query_vector],
    anns_field="chunks[emb]",
    param={
        "params": {
            "radius": 0.80,
            "range_filter": 0.95,
        },
    },
    limit=10,
    expr='element_filter(chunks, $[section] == "index")',
)

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

In questo esempio, solo la sotto-richiesta chunks[emb] utilizza i parametri di ricerca per intervallo. La richiesta StructArray segue comunque la semantica a livello di elemento: il limite dell’intervallo si applica ai risultati corrispondenti agli elementi Struct prima che la ricerca ibrida combini e riclassifichi i risultati.

Interpretazione dei risultati dell’intervallo

Elemento del risultatoSignificato
idChiave primaria dell’entità che contiene l’elemento Struct corrispondente.
distance o punteggioIl punteggio o la distanza tra il vettore di query e il vettore dell'elemento Struct corrispondente.
offsetPosizione, a partire da zero, dell’elemento Struct corrispondente nel campo StructArray al momento della restituzione.
Chiavi primarie ripetutePossibile. Più di un elemento Struct nella stessa entità può rientrare nell'intervallo specificato.
limitSi applica ai risultati relativi agli elementi, non alle entità padre univoche.

Limitazioni

  • Non utilizzare una query di tipo " EmbeddingList " né una metrica " MAX_SIM* " per la ricerca per intervallo sui sottocampi vettoriali di StructArray. La ricerca a livello di EmbeddingList non supporta la ricerca per intervallo.

  • Non combinare la ricerca per intervallo con la ricerca raggruppata. Se è necessario un risultato per ogni entità padre, eseguire una ricerca a livello di elemento senza parametri di intervallo e utilizzare il raggruppamento dove supportato.

  • La ricerca per intervallo ibrida è supportata per i campi vettoriali a livello di elemento di StructArray. Non è supportata per le richieste StructArray a livello di EmbeddingList.

Errori comuni

  • Eseguire la ricerca per intervallo su chunks[emb_list_vector], che è destinato alla ricerca a livello di EmbeddingList.

  • Utilizzo di ` MAX_SIM_COSINE ` al posto di una metrica standard come ` COSINE ` per la ricerca per intervallo a livello di elemento.

  • Utilizzo di una query EmbeddingList al posto di una normale query vettoriale.

  • Aspettarsi che i risultati della ricerca per intervallo siano univoci per entità padre. La ricerca per intervallo restituisce risultati corrispondenti a elementi Struct.

  • Utilizzo di chunks.emb al posto della sintassi richiesta per il percorso del sottocampo chunks[emb].

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 per intervallo, consultare Ricerca filtrata con StructArray.

  3. Per restituire al massimo un risultato per entità padre, ove supportato, leggere Ricerca raggruppata con StructArray.

  4. Per verificare i limiti di ricerca specifici per versione, consultare Limiti di StructArray.