Milvus
Zilliz
  • Home
  • Blog
  • Presentazione dell'indice Ngram di Milvus: Corrispondenza di parole chiave e query LIKE più veloci per i carichi di lavoro degli agenti

Presentazione dell'indice Ngram di Milvus: Corrispondenza di parole chiave e query LIKE più veloci per i carichi di lavoro degli agenti

  • Engineering
December 16, 2025
Chenjie Tang

Nei sistemi ad agenti, il recupero del contesto è un elemento fondamentale dell'intera pipeline, che fornisce la base per il ragionamento, la pianificazione e l'azione a valle. La ricerca vettoriale aiuta gli agenti a recuperare un contesto semanticamente rilevante, che cattura l'intento e il significato in insiemi di dati grandi e non strutturati. Tuttavia, la rilevanza semantica da sola spesso non è sufficiente. Le pipeline di agenti si affidano anche alla ricerca full-text per rispettare i vincoli di parole chiave esatte, come nomi di prodotti, chiamate di funzioni, codici di errore o termini giuridicamente significativi. Questo strato di supporto garantisce che il contesto recuperato non solo sia pertinente, ma soddisfi anche esplicitamente i requisiti testuali.

I carichi di lavoro reali riflettono costantemente questa esigenza:

  • Gli assistenti all'assistenza clienti devono trovare conversazioni che menzionano un prodotto o un ingrediente specifico.

  • I copiloti di codifica cercano snippet contenenti il nome esatto di una funzione, una chiamata API o una stringa di errore.

  • Gli agenti legali, medici e accademici filtrano i documenti alla ricerca di clausole o citazioni che devono apparire alla lettera.

Tradizionalmente, i sistemi si occupano di questo aspetto con l'operatore SQL LIKE. Una query come name LIKE '%rod%' è semplice e ampiamente supportata, ma in condizioni di elevata concorrenza e di grandi volumi di dati, questa semplicità comporta notevoli costi in termini di prestazioni.

  • Senza un indice, una query LIKE scansiona l'intero archivio di contesto e applica la corrispondenza dei pattern riga per riga. Con milioni di record, anche una singola query può richiedere secondi, troppo lenti per le interazioni in tempo reale con gli agenti.

  • Anche con un indice invertito convenzionale, i modelli jolly come %rod% rimangono difficili da ottimizzare perché il motore deve comunque attraversare l'intero dizionario ed eseguire la corrispondenza dei modelli su ogni voce. L'operazione evita le scansioni di riga, ma rimane fondamentalmente lineare, con miglioramenti solo marginali.

Questo crea una chiara lacuna nei sistemi di reperimento ibridi: la ricerca vettoriale gestisce in modo efficiente la rilevanza semantica, ma il filtraggio delle parole chiave esatte diventa spesso la fase più lenta della pipeline.

Milvus supporta in modo nativo la ricerca ibrida vettoriale e full-text con filtraggio dei metadati. Per risolvere i limiti della corrispondenza delle parole chiave, Milvus introduce l'indice Ngram, che migliora le prestazioni di LIKE dividendo il testo in piccole sottostringhe e indicizzandole per una ricerca efficiente. Questo riduce drasticamente la quantità di dati esaminati durante l'esecuzione delle query, fornendo query LIKE da decine a centinaia di volte più veloci in carichi di lavoro agenziali reali.

Il resto del post illustra il funzionamento dell'indice Ngram in Milvus e ne valuta le prestazioni in scenari reali.

Cos'è l'indice Ngram?

Nei database, il filtraggio del testo viene comunemente espresso con SQL, il linguaggio di interrogazione standard utilizzato per recuperare e gestire i dati. Uno degli operatori di testo più utilizzati è LIKE, che supporta la corrispondenza di stringhe basata su modelli.

Le espressioni LIKE possono essere raggruppate in quattro tipi di pattern comuni, a seconda di come vengono utilizzati i caratteri jolly:

  • Corrispondenza prefissata (name LIKE '%rod%'): Corrisponde ai record in cui la sottostringa asta appare in qualsiasi punto del testo.

  • Corrispondenza di prefisso (name LIKE 'rod%'): Corrisponde ai record il cui testo inizia con rod.

  • Corrispondenza di suffisso (name LIKE '%rod'): Corrisponde ai record il cui testo termina con rod.

  • Corrispondenza con caratteri jolly (name LIKE '%rod%aab%bc_de'): Combina condizioni multiple di sottostringa (%) con caratteri jolly singoli (_) in un unico schema.

Sebbene questi modelli differiscano per aspetto ed espressività, l'indice Ngram di Milvus li accelera tutti utilizzando lo stesso approccio di base.

Prima di costruire l'indice, Milvus divide ogni valore testuale in brevi sottostringhe sovrapposte di lunghezza fissa, note come n-grammi. Ad esempio, quando n = 3, la parola "Milvus" viene scomposta nei seguenti 3-grammi: "Mil", "ilv", "lvu" e "vus". Ogni n-gramma viene quindi memorizzato in un indice invertito che mappa la sottostringa con l'insieme degli ID dei documenti in cui compare. Al momento dell'interrogazione, le condizioni di LIKE vengono tradotte in combinazioni di ricerche di n-grammi, consentendo a Milvus di filtrare rapidamente la maggior parte dei record non corrispondenti e di valutare il modello rispetto a un insieme di candidati molto più ridotto. In questo modo si trasformano le costose scansioni di stringhe in efficienti interrogazioni basate su indici.

Due parametri controllano come viene costruito l'indice Ngram: min_gram e max_gram. Insieme, definiscono la gamma di lunghezze delle sottostringhe che Milvus genera e indicizza.

  • min_gram: La lunghezza della sottostringa più breve da indicizzare. In pratica, questo parametro stabilisce anche la lunghezza minima della sottostringa della query che può beneficiare dell'indice Ngram.

  • max_gram: La lunghezza della sottostringa più lunga da indicizzare. Al momento dell'interrogazione, determina anche la dimensione massima della finestra utilizzata quando si dividono le stringhe di query più lunghe in n-grammi.

Indicizzando tutte le sottostringhe contigue di lunghezza compresa tra min_gram e max_gram, Milvus stabilisce una base coerente ed efficiente per accelerare tutti i tipi di pattern LIKE supportati.

Come funziona l'indice Ngram?

Milvus implementa l'indice Ngram in un processo a due fasi:

  • Costruire l'indice: Generare n-grammi per ogni documento e costruire un indice invertito durante l'ingestione dei dati.

  • Accelerare le query: Utilizzare l'indice per restringere la ricerca a un piccolo insieme di candidati, quindi verificare le corrispondenze esatte di LIKE su tali candidati.

Un esempio concreto facilita la comprensione di questo processo.

Fase 1: creazione dell'indice

Decomporre il testo in n-grammi:

Supponiamo di indicizzare il testo "Apple" con le seguenti impostazioni:

  • min_gram = 2

  • max_gram = 3

In base a questa impostazione, Milvus genera tutte le sottostringhe contigue di lunghezza 2 e 3:

  • 2-grammi: Ap, pp, pl, le

  • 3-grammi: App, ppl, ple

Costruire un indice invertito:

Consideriamo ora un piccolo set di dati di cinque record:

  • Documento 0: Apple

  • Documento 1: Pineapple

  • Documento 2: Maple

  • Documento 3: Apply

  • Documento 4: Snapple

Durante l'ingestione, Milvus genera n-grammi per ogni record e li inserisce in un indice invertito. In questo indice:

  • Lechiavi sono n-grammi (sottostringhe).

  • I valori sono elenchi di ID di documenti in cui compare l'n-gramma.

"Ap"  -> [0, 3]
"App" -> [0, 3]
"Ma"  -> [2]
"Map" -> [2]
"Pi"  -> [1]
"Pin" -> [1]
"Sn"  -> [4]
"Sna" -> [4]
"ap"  -> [1, 2, 4]
"apl" -> [2]
"app" -> [1, 4]
"ea"  -> [1]
"eap" -> [1]
"in"  -> [1]
"ine" -> [1]
"le"  -> [0, 1, 2, 4]
"ly"  -> [3]
"na"  -> [4]
"nap" -> [4]
"ne"  -> [1]
"nea" -> [1]
"pl"  -> [0, 1, 2, 3, 4]
"ple" -> [0, 1, 2, 4]
"ply" -> [3]
"pp"  -> [0, 1, 3, 4]
"ppl" -> [0, 1, 3, 4]

Ora l'indice è completamente costruito.

Fase 2: accelerare le query

Quando viene eseguito un filtro LIKE, Milvus utilizza l'indice Ngram per accelerare la valutazione delle query attraverso i seguenti passaggi:

1. Estrazione del termine della query: Le sottostringhe contigue senza caratteri jolly vengono estratte dall'espressione LIKE (ad esempio, '%apple%' diventa apple).

2. Decomposizione del termine della query: Il termine della query viene scomposto in n-grammi in base alla sua lunghezza (L) e alle configurazioni min_gram e max_gram.

3. Cerca ogni grammo e interseca: Milvus cerca gli n-grammi della query nell'indice invertito e interseca i loro elenchi di ID documento per produrre un piccolo insieme di candidati.

4. Verifica e restituisce i risultati: La condizione originale di LIKE viene applicata solo a questo insieme di candidati per determinare il risultato finale.

In pratica, il modo in cui una query viene suddivisa in n-grammi dipende dalla forma del modello stesso. Per vedere come funziona, ci concentreremo su due casi comuni: le corrispondenze infix e le corrispondenze wildcard. Le corrispondenze a prefisso e a suffisso si comportano allo stesso modo di quelle a infisso, quindi non le tratteremo separatamente.

Corrispondenza infix

Per una corrispondenza infix, l'esecuzione dipende dalla lunghezza della sottostringa letterale (L) rispetto a min_gram e max_gram.

1. min_gram ≤ L ≤ max_gram (ad esempio, strField LIKE '%ppl%')

La sottostringa letterale ppl rientra interamente nell'intervallo di n-grammi configurato. Milvus cerca direttamente l'n-gramma "ppl" nell'indice invertito, producendo gli ID dei documenti candidati [0, 1, 3, 4].

Poiché il letterale stesso è un n-gramma indicizzato, tutti i candidati soddisfano già la condizione infix. La fase di verifica finale non elimina alcun record e il risultato rimane [0, 1, 3, 4].

2. L > max_gram (ad esempio, strField LIKE '%pple%')

La sottostringa letterale pple è più lunga di max_gram, quindi viene scomposta in n-grammi sovrapposti usando una finestra di max_gram. Con max_gram = 3, si ottengono gli n-grammi "ppl" e "ple".

Milvus cerca ogni n-gramma nell'indice invertito:

  • "ppl"[0, 1, 3, 4]

  • "ple"[0, 1, 2, 4]

Intersecando queste liste si ottiene l'insieme candidato [0, 1, 4]. Il filtro originale LIKE '%pple%' viene quindi applicato a questi candidati. Tutti e tre soddisfano la condizione, quindi il risultato finale rimane [0, 1, 4].

3. L < min_gram (ad esempio, strField LIKE '%pp%')

La sottostringa letterale è più corta di min_gram e quindi non può essere scomposta in n-grammi indicizzati. In questo caso, l'indice Ngram non può essere utilizzato e Milvus torna al percorso di esecuzione predefinito, valutando la condizione LIKE attraverso una scansione completa con corrispondenza di pattern.

Corrispondenza con caratteri jolly (ad esempio, strField LIKE '%Ap%pple%')

Questo schema contiene più caratteri jolly, quindi Milvus lo divide prima in letterali contigui: "Ap" e "pple".

Milvus elabora poi ogni letterale in modo indipendente:

  • "Ap" ha lunghezza 2 e rientra nell'intervallo di n-grammi.

  • "pple" è più lungo di max_gram e viene scomposto in "ppl" e "ple".

Questo riduce la query ai seguenti n-grammi:

  • "Ap"[0, 3]

  • "ppl"[0, 1, 3, 4]

  • "ple"[0, 1, 2, 4]

Intersecando queste liste si ottiene un unico candidato: [0].

Infine, il filtro originale LIKE '%Ap%pple%' viene applicato al documento 0 ("Apple"). Poiché non soddisfa il modello completo, l'insieme dei risultati finali è vuoto.

Limiti e compromessi dell'indice Ngram

Sebbene l'indice Ngram possa migliorare significativamente le prestazioni delle query di LIKE, introduce dei compromessi che devono essere presi in considerazione nelle implementazioni reali.

  • Aumento delle dimensioni dell'indice

Il costo principale dell'indice Ngram è l'aumento dell'overhead di memorizzazione. Poiché l'indice memorizza tutte le sottostringhe contigue di lunghezza compresa tra min_gram e max_gram, il numero di n-grammi generati cresce rapidamente con l'espandersi di questo intervallo. Ogni lunghezza aggiuntiva di n-grammi aggiunge di fatto un'altra serie completa di sottostringhe sovrapposte per ogni valore di testo, aumentando sia il numero di chiavi dell'indice sia i relativi elenchi di inserimento. In pratica, l'espansione dell'intervallo di un solo carattere può raddoppiare le dimensioni dell'indice rispetto a un indice invertito standard.

  • Non è efficace per tutti i carichi di lavoro

L'indice Ngram non accelera tutti i carichi di lavoro. Se i modelli di query sono molto irregolari, contengono letterali molto brevi o non riescono a ridurre il set di dati a un piccolo insieme di candidati nella fase di filtraggio, il vantaggio in termini di prestazioni può essere limitato. In questi casi, l'esecuzione delle query può ancora avvicinarsi al costo di una scansione completa, anche se l'indice è presente.

Valutazione delle prestazioni dell'indice Ngram su query LIKE

L'obiettivo di questo benchmark è quello di valutare l'efficacia dell'indice Ngram nell'accelerare le query LIKE.

Metodologia del test

Per contestualizzare le sue prestazioni, lo confrontiamo con due modalità di esecuzione di base:

  • Master: Esecuzione bruta senza alcun indice.

  • Master-invertito: Esecuzione con un indice invertito convenzionale.

Abbiamo progettato due scenari di test per coprire diverse caratteristiche dei dati:

  • Set di dati di testo Wiki: 100.000 righe, con ogni campo di testo troncato a 1 KB.

  • Dataset di parole singole: 1.000.000 di righe, dove ogni riga contiene una singola parola.

In entrambi gli scenari, vengono applicate in modo coerente le seguenti impostazioni:

  • Le query utilizzano lo schema di corrispondenza infix (%xxx%).

  • L'indice Ngram è configurato con min_gram = 2 e max_gram = 4

  • Per isolare i costi di esecuzione delle query ed evitare l'overhead della materializzazione dei risultati, tutte le query restituiscono count(*) invece di set di risultati completi.

Risultati

Test per wiki, ogni riga è un testo wiki con lunghezza del contenuto troncata di 1000, 100K righe

LetteraleTempo (ms)VelocizzazioneConteggio
Maestrostadio207.8335
Master-invertito2095335
Ngramma1.09190 / 1922335
Maestroscuola secondaria204.8340
Maestro invertito2000340
Ngramma1.26162.5 / 1587340
Il Masterè una scuola secondaria coeducativa e sponsorizzata223.91
Master invertito21001
Ngramma1.69132.5 / 1242.61

Test per parole singole, 1M di righe

LetteraleTempo(ms)AccelerazioneConteggio
Masterna128.640430
Maestro invertito66.540430
Ngram1.3893.2 / 48.240430
Maestronat1225200
Master invertito65.15200
Ngram1.2796 / 51.35200
Maestronati118.81630
Master invertito66.91630
Ngramma1.2198.2 / 55.31630
Maestronatio118.41100
Maestro invertito65.11100
Ngramma1.3389 / 48.91100
Maestronazione1181100
Maestro invertito63.31100
Ngramma1.484.3 / 45.21100

Nota: questi risultati si basano su benchmark condotti a maggio. Da allora, il ramo Master è stato sottoposto a ulteriori ottimizzazioni delle prestazioni, quindi il divario di prestazioni osservato qui dovrebbe essere minore nelle versioni attuali.

I risultati dei benchmark evidenziano un chiaro schema: l'indice Ngram accelera significativamente le query LIKE in tutti i casi, e la velocità di esecuzione delle query dipende fortemente dalla struttura e dalla lunghezza dei dati testuali sottostanti.

  • Per i campi di testo lunghi, come i documenti in stile Wiki troncati a 1.000 byte, i guadagni di prestazioni sono particolarmente pronunciati. Rispetto a un'esecuzione brutale senza indice, l'indice Ngram raggiunge una velocità di circa 100-200×. Se confrontato con un indice invertito convenzionale, il miglioramento è ancora più netto e raggiunge i 1.200-1.900×. Questo perché le interrogazioni LIKE su testi lunghi sono particolarmente costose per gli approcci di indicizzazione tradizionali, mentre le ricerche di n-grammi possono restringere rapidamente lo spazio di ricerca a un insieme molto piccolo di candidati.

  • Sui set di dati costituiti da voci di una sola parola, i guadagni sono minori ma comunque sostanziali. In questo scenario, l'indice Ngram funziona circa 80-100× più velocemente rispetto all'esecuzione bruta e 45-55× più velocemente rispetto a un indice invertito convenzionale. Sebbene i testi più brevi siano intrinsecamente più economici da analizzare, l'approccio basato sugli n-grammi evita comunque i confronti non necessari e riduce costantemente il costo delle query.

Conclusione

L'indice Ngram accelera le query di LIKE suddividendo il testo in n-grammi di lunghezza fissa e indicizzandoli con una struttura invertita. Questo progetto trasforma la costosa corrispondenza delle sottostringhe in efficienti ricerche di n-grammi seguite da una verifica minima. Di conseguenza, si evitano le scansioni di tutto il testo e si conserva l'esatta semantica di LIKE.

In pratica, questo approccio è efficace in un'ampia gamma di carichi di lavoro, con risultati particolarmente buoni per la corrispondenza fuzzy su campi di testo lunghi. L'indice Ngram è quindi adatto a scenari in tempo reale come la ricerca di codici, l'assistenza agli agenti, il recupero di documenti legali e medici, le basi di conoscenza aziendali e la ricerca accademica, dove la corrispondenza precisa delle parole chiave rimane essenziale.

Allo stesso tempo, l'indice Ngram trae vantaggio da un'attenta configurazione. La scelta dei valori appropriati di min_gram e max_gram è fondamentale per bilanciare le dimensioni dell'indice e le prestazioni delle query. Se regolato in modo da riflettere i modelli di query reali, l'indice Ngram fornisce una soluzione pratica e scalabile per le query LIKE ad alte prestazioni nei sistemi di produzione.

Per ulteriori informazioni sull'indice Ngram, consultare la documentazione qui sotto:

Avete domande o volete un approfondimento su una qualsiasi funzione dell'ultima versione di Milvus? Unitevi al nostro canale Discord o inviate problemi su GitHub. È anche possibile prenotare una sessione individuale di 20 minuti per ottenere approfondimenti, indicazioni e risposte alle vostre domande tramite Milvus Office Hours.

Per saperne di più sulle caratteristiche di Milvus 2.6

    Try Managed Milvus for Free

    Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.

    Get Started

    Like the article? Spread the word

    Continua a Leggere