Core Concepts
This page explains ToriiDB's store, entry, type, JSON-field, expiration, and query semantics.
Store, Session, and Database
A Store owns 16 independent databases. New stores start on database 0, and Select(index) accepts indexes from 0 through 15. Each database has separate memory and persistence files.
Store.Session() creates a lightweight Session that shares all stored data and embedding configuration but keeps an independent selected-database index. This lets multiple callers work with different logical databases through one store.
Always call Close() when the store is no longer needed. Closing waits for asynchronous vector attachment and compacts loaded AOF files.
Entries and Value Types
Each key maps to an Entry containing the key, raw value, detected ValueType, creation and update timestamps, optional expiration, optional vector, and an internal parsed JSON cache.
| Type | Detection rule | TYPE result |
|---|---|---|
| JSON | Valid object or array JSON | json |
| Integer | Parses as base-10 int64 |
int |
| Float | Parses as float64 after integer detection |
float |
| Boolean | Exactly true or false |
bool |
| Date | RFC 3339 or YYYY-MM-DD |
date |
| String | Any value not matched above | string |
Entry.Value() exposes the raw string. Entry.JSON() serializes the complete persisted representation, including the otherwise unexported raw value.
Set Semantics
Set is an upsert by default. SetNX only succeeds when the top-level key does not exist, while SetXX only succeeds when it does exist. The command form accepts the same flags:
SET <key> <value> [NX|XX] [seconds] [VECTOR]
A positive trailing seconds value becomes an absolute expiration time. A plain overwrite clears an existing vector because the old embedding no longer represents the new value.
JSON Documents and Dot Notation
Commands split the first dot in key.field.nested into the top-level key and a nested path. Maps use property names; arrays use decimal indexes.
SET user {"name":"Torii","profile":{"level":1},"tags":["go","db"]}
GET user.profile.level
SET user.profile.level 2
GET user.tags.0
DEL user.profile.level
A field-level SET creates missing map levels, but it does not extend arrays. Array indexes must already exist and be within bounds. Field mutation requires a JSON object at the top level.
The parsed cache avoids decoding JSON repeatedly. All JSON write paths update both the raw serialized value and the parsed object before releasing the database write lock.
Numeric Mutation
INCR <key> [delta] changes an existing integer or float. When dot notation is present, IncrField locates a numeric value in the parsed JSON object, adds the delta, and persists the complete document.
Missing keys, missing fields, non-numeric values, and invalid array paths fail without producing a new numeric entry.
Expiration
| Operation | Meaning |
|---|---|
TTL key |
Remaining seconds, -1 without expiration, or missing when expired/absent |
EXPIRE key seconds |
Sets expiration relative to now |
EXPIREAT key timestamp |
Sets an absolute Unix timestamp |
PERSIST key |
Removes expiration |
Expiration is enforced by point reads, scan commands, and a once-per-minute cleanup timer. A key that has passed its timestamp is treated as absent even if physical cleanup has not run yet.
Scans and Queries
KEYS matches top-level keys with Go path.Match glob syntax and sorts results lexicographically. FIND compares complete raw values and returns newest entries first. QUERY evaluates fields in JSON documents and also returns newest entries first.
Supported comparison operators are EQ/=, NE/!=, GT/>, GTE/GE/>=, LT/<, LTE/LE/<=, and LIKE. Numeric ordering operators require both operands to parse as numbers.
FIND like *database* LIMIT 10
QUERY profile.level >= 2 AND active = true LIMIT 10
QUERY ( role = admin OR role = editor ) AND NOT disabled = true
AND binds more tightly than OR; NOT applies recursively to the next expression; parentheses group expressions. Because tokenization is whitespace-based, parentheses should be separated or attached to adjacent tokens in forms accepted by the parser.
Reserved Namespace
The __torii: prefix is reserved for internal records such as embedding cache entries. Scan-style operations hide these records so they do not appear in normal application results. Point lookups are intentionally not blocked, which allows inspection during debugging.