CollectionDb (v2, Beta)

CollectionDb is the v2 storage engine โ€” the "type": "collection" table. It's a schema-flexible, columnar store: you can POST raw JSON and let Aito infer the schema, evolve that schema as your data grows, and edit it declaratively. This guide is the reference for what a collection exposes. v2 is in beta.

Collection vs table

collection (rep2)table (rep1)
EngineCollectionDb (new, columnar)TableDb (production)
Schemaflexible โ€” infer from JSON, evolve incrementallyfixed at creation
Storagecompact columnar, memory-mapped readsrow-oriented
Use whenyou want the v2 engine, JSON ingest, schema evolutionyou need v1 parity today

table is still the default; create a collection with "type": "collection", or let /import create one for you.

The v2 engine is built for collections. A rep1 table can be reached through /api/v2 for basic filtering and predict, but its v2 support is deliberately minimal (v1 is being retired) โ€” e.g. the text matchers $match / $search are collection-only. To use v2 fully on data in a v1 table, migrate it to a collection or branch it into an env to trial v2 โ€” see Which Query Type? โ†’ v2 works on v2 collections.

Ingesting data

EndpointWhat it does
POST /api/v2/data/{table}/importSchema-flexible import. POST a JSON array; Aito infers column types, creates the table if absent, and appends if present. ?type=table makes a rep1 table instead.
POST /api/v2/data/{table}Insert one document.
POST /api/v2/data/{table}/batchInsert an array of documents.
POST /api/v2/data/{table}/streamInsert NDJSON (one object per line).
POST /api/v2/schema/_inferInfer a schema from example rows without creating anything (a dry run).
POST /api/v2/data/events/import
[
  { "user": "ann", "action": "view",  "ts": "2026-06-01" },
  { "user": "bob", "action": "buy",   "ts": "2026-06-02", "amount": 19.0 }
]

Type inference maps JSON scalars to Int/Long/Decimal/Boolean/String, dates to Date, and nested/irregular values to Json. When two rows disagree on a field's type, the column widens to Json (lossless) rather than failing.

Schema evolution

A collection's schema isn't frozen:

  • New fields appear automatically on /import โ€” importing rows with a field the table doesn't have extends the schema; existing rows treat it as null.
  • Heterogeneous-schema merge โ€” segments written with different schemas merge transparently (the read side takes the union), so cross-insert evolution just works.
  • Declarative changes โ€” describe the schema you want and apply the diff (see Schema Migration ยง plan & apply): POST .../{table}/_plan classifies each column (add / rebuild / drop / rejected / no-op); _apply converges in one commit (refuses lossy changes; data-loss drops need ?confirm=true; idempotent).
  • Single-column edits โ€” PUT /api/v2/schema/{table}/{column} adds a column (optional value backfill) or alters an existing one's type/analyzer in place (the engine re-indexes; durable across optimize; incompatible alters rejected).

Known limitation. Automatic new-column inference currently fires on bulk /import only โ€” not on incremental single/batch inserts, which validate against the existing schema. To add a field outside import, use _apply or PUT .../{column}.

Maintaining a collection

EndpointWhat it does
POST /api/v2/data/{table}/optimizeConsolidate segments into an optimized state (faster queries).
POST /api/v2/data/_modifyAtomic by-key ops: update / upsert / delete a document, plus maintenance (optimize, copy, warm the linkage cache).
POST /api/v2/data/_deleteDelete rows matching a where-clause.

Writes land as segments and are queryable immediately; optimize merges them for steady-state query speed (it's the rep2 analogue of a compaction). See Schema Migration & Maintenance for worked examples of bulk backfill, plan/apply, and atomic _modify operations.

Nullable & sparse columns

Scalar nullable columns carry an honest defined-mask โ€” a real null that does not collide with 0, "", or false โ€” and round-trip through persistence and merge. Query them with $exists. (Non-scalar nullable inners โ€” nullable arrays/Json โ€” are still sentinel-based; that's a tracked follow-up.)