Documents Storage

SoliDB's core storage engine. High-performance, transactional Key-Value storage for JSON documents.

Overview

Document collections are the default storage type in SoliDB. They provide flexible, schema-free storage for JSON documents while maintaining full ACID guarantees.

Fast Key-Value

Optimized for point lookups and range scans using primary keys.

JSON Native

Store arbitrary JSON structures. No rigid schemas required.

Transactional

Multi-document, multi-collection ACID transactions supported out of the box.

Creating a Document Collection

Create a collection with type: "document" (default).

POST /_api/database/:db/collection
curl -X POST http://localhost:6745/_api/database/_system/collection \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{ "name": "users", "type": "document" }'

JSON Schema Validation

Enforce data integrity by attaching a JSON Schema to your collection. SoliDB supports three validation modes:

Strict
Rejects any document that violates the schema.
Lenient
Accepts invalid documents but logs a warning.
Off
Disables validation (default).

Create with Schema

POST /_api/database/:db/collection
curl -X POST http://localhost:6745/_api/database/_system/collection \
-H "Authorization: Bearer $TOKEN" \
-d '{ "name": "products", "schema": { "type": "object", "required": ["name", "price"], "properties": { "name": { "type": "string" }, "price": { "type": "number", "minimum": 0 } } }, "validationLevel": "strict" }'

Validation Error

Attempting to insert an invalid document in strict mode will return a 400 Bad Request error with details about the schema violation.

Basic Operations

Insert Document

POST /_api/document/:db/:collection
curl -X POST http://localhost:6745/_api/document/_system/users \
-d '{ "name": "Alice", "email": "alice@example.com" }'

Read Document

GET /_api/document/:db/:collection/:key
curl http://localhost:6745/_api/document/_system/users/123

Time Travel (document versioning)

Enable versioning on a collection and every single-document insert/update/delete records an immutable version in the same atomic write. Read the past with two SDBQL functions:

Turning it on

Turn it on when you create the collection — pass versioning: true:

POST /_api/database/<db>/collection
{ "name": "orders", "type": "document", "versioning": true }

Or toggle it on an existing collection through its properties (send false to stop recording new versions — existing history is kept):

PUT /_api/database/<db>/collection/orders/properties
{ "versioning": true }

In the admin UI it is a checkbox in the New collection dialog and a toggle on the collection page.

DOC_AS_OF — a document as it was

DOC_AS_OF(collection, key, timestamp) returns the newest version at or before timestamp (epoch milliseconds, or an RFC3339 string), or null if the document did not exist then.

RETURN DOC_AS_OF("orders", "o1", "2026-07-01T00:00:00Z")
DOC_HISTORY — the full timeline

DOC_HISTORY(collection, key) returns every version, newest first: [{ ts, deleted, value }, ...].

RETURN DOC_HISTORY("orders", "o1")
SYSTEM_TIME AS OF — scan the past

Iterate every live document as of a timestamp. Full history scan, no indexes.

FOR o IN orders SYSTEM_TIME AS OF "2026-07-01T00:00:00Z"
  RETURN o
SNAPSHOT_DIFF — what changed

Compare two points in time: { inserted, updated, deleted }.

RETURN SNAPSHOT_DIFF("orders", t1, t2)

Scope. Versioning is opt-in per collection and retained up to SOLIDB_MAX_VERSIONS (default 100). Single-document writes, insert_batch / upsert_batch, and transactional write batches record history. Secondary indexes are current-version only. Application validity uses VALID_TIME on valid_from/valid_to, not this log.