Il meccanismo · 0.1.0b4

Una singola ricerca nella directory.
Una singola scansione contigua.

La ricerca vettoriale filtrata è di solito uno scatter-gather su un indice che non sa nulla del tuo filtro. Telys controlla invece il layout fisico: sulla chiave di partizione, nearest-neighbours-where-key-equals-x è una ricerca O(1) nella directory più una singola scansione sequenziale di un blocco contiguo. Questa pagina illustra il runtime attualmente in produzione, poi l'architettura verso cui sta convergendo — etichettata come spec.

Panel 01 · Oggi — il runtime in produzione
01 Layout fisico

Il motore controlla dove vive ogni vettore.

Una collection dichiara partition_by alla creazione e il layout segue la chiave. Il segmento base è raggruppato per partizione — ogni chiave mappa a una singola slice contigua — e le scritture recenti risiedono accanto in un delta mutabile a forma Arrow.

Segmento base

Raggruppato per partizione

Vettori memorizzati ordinati per chiave di partizione, così ogni partizione è un blocco contiguo. Una query con scope legge una singola sequenza di memoria, non righe sparse in un indice.

Directory di partizione

O(1) key → slice

Una directory mappa ogni valore di partizione al suo (offset, length) nel segmento base. Risolvere il filtro è una ricerca nel dizionario, non un attraversamento dell'indice.

Delta mutabile

Scritture a forma Arrow

add e upsert accodano qui, ogni riga marcata con un LSN di scrittura monotono. Il delta è interrogabile immediatamente e si unisce alla slice base attraverso un unico percorso di scansione.

02 Il percorso di lettura

Cosa esegue una query con scope.

Query

col.search(qvec, where={"tenant_id": "acme"}, top_k=10)

Il filtro indica la chiave di partizione con cui è stata creata la collection.

Directory di partizione

Ricerca O(1): il valore di partizione si risolve in (offset, length) nel segmento base. Nessuna generazione di candidati, nessun punto di ingresso nel grafo.

Scansione slice contigua

Scoring esatto SIMD su un singolo blocco sequenziale. Il recall su questo percorso è 1.0 — è una scansione, non un'approssimazione. I valori p50/p95 misurati per questo passaggio sono pubblicati nella pagina dei benchmark, ciascuno legato alla propria soglia di recall e al proprio rig.

Unione delta

Le righe con la stessa chiave nel delta a forma di Arrow vengono valutate attraverso lo stesso percorso. Una scrittura è visibile alla query immediatamente successiva.

Visibilità MVCC

I risultati vengono filtrati all'LSN dello snapshot: le versioni con tombstone o superate non emergono mai. Top-k restituisce il payload explain allegato.

Le partizioni sovradimensionate seguono un fork dichiarato: build_ivf posiziona un IVF per partizione su qualsiasi partizione oltre la soglia di righe, e le query vi vengono instradate con un rerank esatto — calibrato rispetto a un floor di recall, e nominato nel piano.

03 Il fork explain

Ogni risultato nomina il proprio piano.

explain=True restituisce il piano fisico effettivamente seguito dalla query. Sulla chiave di partizione si ottiene la scansione a slice contigua. Le partizioni sovradimensionate dichiarano il fork IVF. I filtri fuori chiave ricadono sullo scatter-gather — e il payload spiega perché.

explain
hits = col.search(qvec, where={"tenant_id": "acme"}, top_k=10, explain=True)

hits["explain"]["plan"]
# on the partition key  → "PartitionSliceExactF32"   # one contiguous slice, exact, recall 1.0
# oversized partition   → "PartitionIVFRerankF32"   # per-partition IVF + exact rerank
# off-key filter        → "ScatterGatherExact"      # fallback — and it says why:

hits["explain"]["fallback_reason"]
# "path is not the physical partition key"
04 Scritture e tempo

Nulla viene sovrascritto. Le versioni vengono superate.

Il modello di scrittura è MVCC append-only. upsert scrive una nuova versione di un id logico e contrassegna la precedente come superata; delete posiziona un tombstone a un delete LSN; snapshot() fissa una vista di lettura consistente; compact() incorpora il delta nella base e scarta ciò che nessuno snapshot può vedere.

python
col.upsert(vectors, ids=ids, metadata=metadata)   # a new version; the prior one is superseded
col.delete(["doc-41"])                            # tombstone at a delete LSN — no in-place erase
lsn = col.snapshot()                              # pin a consistent read view at an LSN
col.compact()                                     # fold delta into base; drop superseded rows
col.build_ivf(min_rows=20000, target_recall=0.98)
ChiamataFunzione
aggiungi / aggiungi_testiInserisce nuove righe. Gli id duplicati vengono rifiutati — una seconda riga fisica per un id logico richiede upsert, per scelta esplicita.
upsert / upsert_textsScrive una nuova versione di un id logico; la versione precedente viene superata, mai sovrascritta in loco.
cerca / cerca_testoTop-k filtrato. explain=True allega il piano fisico al risultato.
deleteApplica un tombstone alle righe logiche a un delete LSN.
compactIncorpora il delta nel segmento base; elimina le versioni con tombstone e quelle superate.
build_ivfCostruisce un IVF per partizione sulle partizioni oltre la soglia di righe, calibrato su un floor di recall.
snapshotRestituisce un LSN che fissa una vista di lettura consistente.
save / statsPersiste la collection su disco; riporta conteggi di righe, partizioni e informazioni sul layout.
Panel 02 · Direzione — la spec dell'architettura

Tutto ciò che segue è specifica, non riferimento API rilasciato. È il substrato verso cui il runtime sta convergendo. La giuntura esposta all'SDK è congelata, quindi la sostituzione sottostante è invisibile ai chiamanti.

05 Il substrato target

Un planner. Un IR piatto. Un executor.

Tre front end convergono in un unico planner, che emette una rappresentazione intermedia fisica piatta, eseguita da un unico executor vettorizzato Mojo direttamente sui buffer Arrow.

Front end

Il modello di memoria (remember · recall · as_of), le API di query (point_get · scan · search · hybrid_search) e il fabric. Un unico contratto d'ingresso; nessun engine per API.

Un planner

Pianificazione logica e fisica in un unico punto. La selettività è stimata dalle statistiche di segmento; il piano è esplicito e restituito insieme al risultato.

Un IR piatto

Un array piatto di operatori legati da slot interi. Il registro inter-operatore è un row set — una bitmap, row-id ordinati o un vettore di selezione.

Un executor Mojo

Esecuzione vettorizzata su buffer Arrow e array di candidati FAISS. L'hot path SIMD rimane fuori da Python; le pagine Parquet compresse vengono decodificate prima in scratch buffer.

Arrow delta + WAL

Il layer di mutazione

Un write-ahead log per durabilità e ordinamento, e un delta mutabile a forma di Arrow per visibilità immediata — il layer tabellare che Parquet da solo non offre.

Segmenti Parquet

Sealed, immutabili

Segmenti colonnari compressi e durevoli. Le statistiche del footer guidano il pruning di segmenti e row-group; i file sealed non vengono mai mutati.

sidecar .vidx

FAISS ANN

Indici FAISS per segmento, legati al checksum e alla versione del segmento, mappati in sola lettura con durata vincolata allo snapshot di lettura.

Sidecar scalari + sparsi

Pruning e lessicale

Zone map, bloom filter e bitmap per il pruning; un sidecar BM25 per il recupero sparso e la fusione dei punteggi.

flat IR — insieme di operatori
SCAN  FILTER  PROJECT  POINT_GET  RANGE_GET  AGGREGATE  TOP_K
HASH_JOIN  HASH_GROUP_BY  SORT
ANN_SEARCH  SPARSE_SEARCH  FUSE  RERANK  MATERIALIZE
06 Il percorso di scrittura

Prima il WAL. Visibile immediatamente. Sealed in background.

Append WAL

Frame append-only con checksum e LSN monotoni. Il recovery riproduce i record oltre l'ultimo LSN sealed e tronca al primo checksum non valido.

Arrow delta

La scrittura approda nel delta mutabile ed è immediatamente interrogabile — segmenti sealed e delta si uniscono attraverso un unico percorso di scansione.

Seal in background

Superata una soglia di dimensione, righe o età, il delta viene ordinato e scritto come segmento Parquet con il relativo .vidx e i file sidecar, quindi pubblicato tramite uno swap atomico del manifest.

Compaction

I merge in background fondono i segmenti piccoli, eliminano le righe con tombstone e ricostruiscono i sidecar — a budget controllato, così i deployment on-device restano silenziosi.

I segmenti sealed non vengono mai mutati. Una lettura fissa (snapshot del manifest, LSN); i writer sealed nuovi segmenti e scambiano il manifest senza disturbare i reader in volo. Il garbage collection attende lo snapshot live più vecchio.

07 Filtered ANN come pianificazione

È il filtro a scegliere il piano, non il contrario.

Filtered ANN è pianificazione adattiva per selettività: il planner stima quante righe sopravvivono al filtro dalle statistiche di segmento, poi sceglie la strategia meno costosa che rispetta il contratto di recall.

Selettivo

Prefiltro → esatto

Prima un prefilter scalare o bitmap, poi scoring SIMD esatto sui sopravvissuti. Sotto una soglia di righe l'ANN viene saltato del tutto — scansione esatta, recall 1.0.

Moderato

Scansione allow-bitmap

L'attraversamento ANN porta un allow-bitmap, così l'indice espone solo le righe ammesse dal filtro.

Ampio

ANN → post-filtro

Prima ANN con over-fetch adattivo, poi post-filter. Il filtro rimuove poco, quindi guida la generazione dei candidati.

08 Stato

I gate di correttezza precedono qualsiasi dato di velocità.

Il runtime distribuito è verificato da suite di parità eseguite su entrambe le implementazioni del motore, e ogni query può nominare il piano fisico che ha seguito. Questo è l'ordine delle operazioni: prima i gate di correttezza, poi la misurazione.

I benchmark vengono pubblicati sotto un contratto di equità — recall corrispondente, hardware corrispondente, risultati separati per trasporto, win / tie / lose riportati. I primi risultati misurati sono ora disponibili nella pagina dei benchmark, ogni cifra accompagnata dalle proprie condizioni complete: hardware, dataset, dimensione, selettività, recall e trasporto. Ogni moltiplicatore rimane un'ipotesi al di fuori delle condizioni dichiarate accanto ad esso.

Leggi la metodologia dei benchmarkScopri la superficie del prodotto