Relational parameters #
The cross-type parameters that turn a flat schema into a relational one:
declare a foreign key, opt into reference materialization, and route
placement by the field’s value. They compose — the same org_id field can
declare all four — and the
joins tutorial
walks them end to end against a live node.
references
#
Declares this field as a foreign key into another collection. The value is
the referenced collection’s document key (or, with a field-targeted join,
whatever field the join names).
"org_id": {
"type": "keyword",
"references": {"collection": "orgs"}
}
Writes do NOT fail when the referenced document is missing — a dangling
reference still lands (soft integrity), and the
join query
simply does not match it. Joins through a declared references field
resolve without a second fan-out.
ref
#
(Opt-in, boolean, default: false) Materialize the reference at write
time: the engine stores a hidden column pointing at the referenced
document’s live copy, so joins and reference lookups skip the key
resolution round-trip. Requires references on the same field.
"org_id": {
"type": "keyword",
"references": {"collection": "orgs"},
"ref": true
}
immutable
#
(Boolean, default: false) The field cannot change after the document is
written — updates that touch it are rejected. A field that carries a
references target should be immutable: the reference’s meaning would
silently drift otherwise.
routing
#
(Boolean, default: false) Placement routes by this field’s VALUE: every
write must carry it, and its hash(value) % partitions picks the home
partition — not the document key’s hash. Exactly one field of a collection
may declare routing, and it must be a keyword (scalar, stringified).
"org_id": {
"type": "keyword",
"immutable": true,
"references": {"collection": "orgs"},
"routing": true,
"ref": true
}
Consequences, all fail-closed:
- a write missing the routing field (or carrying
null, an array, or an object) answers400— a document without the value has no home partition; - key-addressed reads and writes (
GET/HEAD/DELETE/UPDATEby_key) require?routing=<value>— a bare key has no home partition either — while the value pointing at the WRONG partition is an honest404; _saltingsplits a hot routing value across a SET of partitions (salt-split) — the parameter this page declares is the one salting operates on.