仕組み · 0.1.0b4

ディレクトリ参照は一度。
スキャンは一度、連続して。

フィルター付きベクトル検索は通常、フィルターを知らないインデックス上のスキャッタ・ギャザーだ。Telysは代わりに物理レイアウトを所有する——パーティションキー上では、nearest-neighbours-where-key-equals-x はO(1)のディレクトリ参照と連続ブロックの一度のシーケンシャルスキャンで完結する。このページでは今日出荷済みのランタイムを解説し、続いて収束先のアーキテクチャを——仕様として明示しながら——説明する。

Panel 01 · 現在 — 出荷済みランタイム
01 物理レイアウト

エンジンがすべてのベクトルの配置を管理する。

コレクションは作成時にpartition_byを宣言し、レイアウトはそのキーに従う。ベースセグメントはパーティションでクラスタリングされ——各キーは一つの連続スライスにマップされる——最近の書き込みはその隣に可変のArrow形式デルタとして配置される。

ベースセグメント

パーティションクラスタリング

ベクトルはパーティションキーでソートして格納され、各パーティションは一つの連続ブロックになる。スコープクエリはメモリの一連続ランを読み取り、インデックス上に散在する行を読まない。

パーティションディレクトリ

O(1) key → スライス

ディレクトリは各パーティション値をベースセグメント内の (offset, length) にマップする。フィルターの解決はディクショナリ参照であり、インデックストラバーサルではない。

可変デルタ

Arrow形式の書き込み

addとupsertはここに追記され、各行に単調増加の書き込みLSNが付与される。デルタは即座にクエリ可能で、一つのスキャンパスを通じてベーススライスとユニオンされる。

02 読み取りパス

スコープクエリが実行すること。

クエリ

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

フィルターはコレクション作成時に指定したパーティションキーを指定する。

パーティションディレクトリ

O(1)参照: パーティション値がベースセグメント内の (offset, length) に解決される。候補生成もグラフエントリポイントも不要だ。

連続スライススキャン

一つの連続ブロック上でSIMD完全スコアリング。このパスのリコールは1.0——近似ではなくスキャンだ。このステップの計測済み p50/p95 はベンチマークページで公開しており、各値はリコールゲートと計測環境に紐付けられている。

デルタユニオン

同一キーの行は、Arrow形式のデルタ内でも同じパスでスコアリングされる。書き込みは直後のクエリから即座に可視となる。

MVCC 可視性

スナップショットLSNでヒットをフィルタリング:トゥームストーン済みおよび上書き済みのバージョンは一切浮上しない。Top-kはexplainペイロードを付帯して返される。

サイズ超過のパーティションは宣言済みのフォークを取る:build_ivfは行数閾値を超えたパーティションにパーティション単位のIVFを配置し、クエリは正確なrerankを伴ってそこへルーティングされる――リコールフロアに対してキャリブレーションされ、プランに明記される。

03 explain フォーク

すべての結果がプランを明示する。

explain=Trueは、クエリが実際に辿った物理プランを返す。パーティションキー上では連続スライススキャンが得られる。サイズ超過のパーティションはIVFフォークを宣言する。キー外フィルタはscatter-gatherにフォールバックし、ペイロードがその理由を示す。

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 書き込みと時間

上書きはない。バージョンが上書きされるのではなく、supersededになる。

書き込みモデルはappend-only MVCCである。upsertは論理idの新バージョンを書き込み、旧バージョンをsupersededとしてマークする。deleteは削除LSNにトゥームストーンを置く。snapshot()は一貫した読み取りビューをピン留めする。compact()はデルタをベースに折り畳み、いかなるスナップショットからも参照されないものを破棄する。

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)
呼び出し動作
追加 / add_texts新規行を挿入する。重複idは拒否される――一つの論理idに対して2行目の物理行を書くには、意図的にupsertが必要となる。
アップサート / upsert_texts論理idの新バージョンを書き込む。旧バージョンはsupersededとなり、インプレースで上書きされることはない。
検索 / search_textフィルタ付きtop-k。explain=Trueは物理プランを結果に付帯する。
delete削除LSNで論理行にトゥームストーンを置く。
compactデルタをベースセグメントに折り畳み、トゥームストーン済みおよびsuperseded済みのバージョンを破棄する。
build_ivf行数閾値を超えたパーティションにパーティション単位のIVFを構築し、リコールフロアに対してキャリブレーションする。
snapshot一貫した読み取りビューをピン留めするLSNを返す。
save / statsコレクションをディスクに永続化し、行数・パーティション数・レイアウト情報を報告する。
Panel 02 · 方向性 — アーキテクチャ仕様

以下はすべて仕様であり、出荷済みAPIリファレンスではない。ランタイムが収束しつつある基盤を示すものである。SDK向けのシームは固定されているため、その下での入れ替えは呼び出し元には不可視となる。

05 ターゲット基盤

プランナーひとつ。フラットIRひとつ。エグゼキュータひとつ。

3つのフロントエンドがひとつのプランナーに降下し、ひとつのフラット物理中間表現を出力する。それをひとつのMojoベクトル化エグゼキュータがArrowバッファ上で直接実行する。

フロントエンド

メモリモデル(remember · recall · as_of)、クエリAPI(point_get · scan · search · hybrid_search)、そしてファブリック。エントリコントラクトはひとつ。API別エンジンは存在しない。

単一プランナー

論理・物理プランニングを一箇所で行う。選択性はセグメント統計から推定され、プランは明示的に結果とともに返される。

フラット IR

整数スロットで結合されたオペレータのフラット配列。オペレータ間レジスタはrow set――ビットマップ、ソート済み行ID、またはセレクションベクタ――である。

Mojo エグゼキュータ

ArrowバッファとFAISS候補配列上でのベクトル化実行。SIMDホットパスはPythonの外に置かれ、圧縮されたParquetページはまずスクラッチバッファにデコードされる。

Arrow デルタ + WAL

ミューテーション層

耐久性と順序付けのための先行書き込みログと、即時可視性のためのミュータブルなArrow形式デルタ――Parquet単体では持ち得ないテーブル層である。

Parquet セグメント

シール済み・イミュータブル

耐久性のある圧縮カラム型セグメント。フッター統計がセグメントおよびrow-groupのプルーニングを駆動し、シール済みファイルは一切変更されない。

.vidx サイドカー

FAISS ANN

セグメント単位のFAISSインデックス。セグメントのチェックサムとバージョンに紐付けられ、読み取りスナップショットのライフタイムに連動して読み取り専用でマップされる。

スカラー + スパース サイドカー

プルーニングと語彙検索

プルーニング用のゾーンマップ・ブルームフィルタ・ビットマップ、およびスパース検索とスコアフュージョン用のBM25サイドカー。

flat IR — オペレータセット
SCAN  FILTER  PROJECT  POINT_GET  RANGE_GET  AGGREGATE  TOP_K
HASH_JOIN  HASH_GROUP_BY  SORT
ANN_SEARCH  SPARSE_SEARCH  FUSE  RERANK  MATERIALIZE
06 書き込みパス

WAL優先。即時可視。バックグラウンドでシール。

WAL 追記

チェックサムと単調増加LSNを持つappend-onlyフレーム。リカバリは最後のシール済みLSN以降のレコードを再生し、最初の不正チェックサムで切り捨てる。

Arrow デルタ

書き込みはミュータブルなデルタに着地し、即座にクエリ可能となる――シール済みセグメントとデルタはひとつのスキャンパスを通じて統合される。

バックグラウンドシール

サイズ、行数、または経過時間のしきい値を超えると、デルタはソートされ、.vidx およびサイドカーとともに Parquet セグメントとして書き込まれ、アトミックなマニフェストスワップによって公開されます。

コンパクション

バックグラウンドマージが小さなセグメントを統合し、トゥームストーン済み行を削除し、サイドカーを再構築します。バジェット制御により、デバイス上のデプロイメントは静粛に保たれます。

シールされたセグメントは変更されません。読み取りはピン留めします(マニフェストスナップショット、LSN)。ライターは新しいセグメントをシールし、処理中のリーダーを妨げることなくマニフェストをスワップします。ガベージコレクションは最古のライブスナップショットを待ちます。

07 プランニングとしてのフィルタ付き ANN

フィルタがプランを選ぶ。その逆ではない。

フィルタ付き ANN は選択性による適応プランニングです。プランナーはセグメント統計からフィルタを通過する行数を推定し、リコール契約を満たす最安戦略を選択します。

高選択

プレフィルタ → 完全一致

スカラーまたはビットマップによるプリフィルタを先に適用し、生存行に対して正確な SIMD スコアリングを実行します。行数がしきい値を下回ると ANN は完全にスキップされ、完全スキャン(リコール 1.0)となります。

中選択

許可ビットマップ走査

ANN トラバーサルは allow-bitmap を保持するため、インデックスはフィルタが許可した行のみを返します。

低選択

ANN → ポストフィルタ

適応的なオーバーフェッチを伴う ANN を先に実行し、その後ポストフィルタを適用します。フィルタの除外が少ないため、候補生成が主導します。

08 ステータス

正確性ゲートは、いかなる速度指標にも先行する。

出荷済みランタイムは、両エンジン実装に対して実行されるパリティスイートで検証されており、すべてのクエリは実行した物理プランを明示できます。ここでの優先順位はこの通りです。正確性ゲートが先、計測が後。

ベンチマークはフェアネス契約のもとで公開されます — リコール一致、ハードウェア一致、トランスポート分離の結果、勝ち/引き分け/負けを報告します。初回計測結果はベンチマークページで公開中であり、全数値にハードウェア、データセット、次元数、セレクティビティ、リコール、トランスポートの完全な条件を付記しています。各乗数は、記載された条件の外では仮説にとどまります。

ベンチマーク手法を読むプロダクト全体を見る