Skip to content

Quickstart

TutorialSQLVectorWASM

A tiny “product search” example: a products table with a name, price, and a 128-dimensional embedding column. We’ll ingest 10,000 rows from CSV, build a vector index, run a “find similar product” query in SQL, then push that logic into a WASM cell.

flowchart LR
  classDef step fill:#1f2640,stroke:#7c5cff,color:#e8eaf0
  classDef out  fill:#1f2640,stroke:#4ade80,color:#4ade80

  S1[1. Create table]:::step --> S2[2. Bulk-load CSV]:::step --> S3[3. Build vector index]:::step --> S4[4. kNN query in SQL]:::step --> S5[5. Deploy WASM cell]:::step --> R[Recommendation service]:::out

Open the REPL (aether-term) and create a typed table. TENSOR(128) is a native, fixed-dimension vector column — not a generic blob.

CREATE TABLE products (
id BIGINT,
hilbert BIGINT USING HILBERT 2D, -- spatial-locality key
name TEXT,
price DOUBLE,
vec TENSOR(128) -- 128-dim vector
);

Two things worth noticing:

  • Schema is enforced at ingest. A row with a missing column or wrong type is rejected — there is no permissive blob fallback.
  • The hilbert column is special. Marking it USING HILBERT 2D tells the engine to use it as a spatial-locality key, so narrow range queries on it skip most of the table.

Load a CSV (10K rows here) with COPY.

COPY products FROM '/path/to/products.csv'
WITH (FORMAT 'csv', HEADER TRUE);
Opt-in Implemented · off by default — enable with BULK_PULSE_V2=1 · set as an env var when starting aetheriusd

For 10K rows brute-force kNN is fine, but in production you want an index. AetheriusDB supports HNSW (graph-based, recall-focused) and IVFFLAT (centroid-based, throughput-focused).

-- HNSW: best recall at small-to-medium k
CREATE INDEX products_vec_hnsw
ON products (vec)
USING HNSW;
-- Or IVFFLAT: lower memory, faster build at very large N
CREATE INDEX products_vec_ivf
ON products (vec)
USING IVFFLAT (n_centroids = 64);

Find the products most similar to a query vector, using cosine distance.

SELECT
id,
name,
price,
TENSOR_INDEX_DISTANCE_AT_COSINE('products_vec_hnsw', :q, 0) AS distance
FROM products
WHERE id = TENSOR_INDEX_NEAREST_ID_AT_COSINE('products_vec_hnsw', :q, 0)
OR id = TENSOR_INDEX_NEAREST_ID_AT_COSINE('products_vec_hnsw', :q, 1)
-- ... rank 2..9 ...
ORDER BY distance ASC;

TENSOR_INDEX_NEAREST_ID_AT_COSINE(index, query, rank) returns the rank-th closest id; TENSOR_INDEX_DISTANCE_AT_COSINE returns its distance. Both consult the index from Step 3.

The SQL above works, but every call pays a round-trip. Deploy a WASM cell so the recommendation logic runs inside the database and returns only the final top-10 ids.

DEPLOY CELL recommend
VERSION 1
FROM '/path/to/recommend.wasm'
ON products
RETURNS TABLE(id BIGINT, score DOUBLE);

Now one call returns final, ranked results:

SELECT * FROM CELL(recommend, :user_vec, k => 10);

You now have a typed table, a vector index, working kNN search, and a deployed WASM cell.