A new universe for your graph data.Meet Galactus DB
GALACTUS DB WIKIDeployment · Queries · Operations

Constraints and shared uniqueness

Wiki / Indexes and constraints

On this page

The failing inserts in this article are intentional examples. Execute them individually against disposable data: an Explorer script stops at its first error.

Uniqueness constraints

A uniqueness constraint guarantees no two nodes with a given label share a value for a property. It is index-backed: declaring one ensures a backing index exists, and enforcement is then a cheap posting-list check.

CREATE CONSTRAINT FOR (u:User) REQUIRE u.id IS UNIQUE;
DROP   CONSTRAINT FOR (u:User) REQUIRE u.id IS UNIQUE;
SHOW CONSTRAINTS;

Behaviour:

  • Enforced on writes — a CREATE or SET that would put a second node on the same (label, property) value fails with a constraint error.
  • Validated at creation — CREATE CONSTRAINT fails if existing data already contains a duplicate for that pair.
  • Backing index is protected — you cannot DROP INDEX on a pair that backs a live constraint; drop the constraint first. (Dropping the constraint leaves the backing index in place; remove it explicitly with DROP INDEX if unwanted.)
CREATE CONSTRAINT FOR (u:User) REQUIRE u.id IS UNIQUE;
CREATE (:User {id: 1});
CREATE (:User {id: 1});      // error: uniqueness violation on :User(id) = 1

Existence constraints

REQUIRE n.prop IS NOT NULL guarantees every node with the label carries the property. It is validated at the statement/transaction boundary (so the order in which a statement sets properties doesn't matter) and at declaration against existing data.

CREATE CONSTRAINT FOR (p:Person) REQUIRE p.name IS NOT NULL;
DROP   CONSTRAINT FOR (p:Person) REQUIRE p.name IS NOT NULL;
CREATE (:Person {age: 5});   // error: missing required property `name`

Node-key constraints

REQUIRE (n.a, n.b) IS NODE KEY is the composite generalisation: every labelled node must carry all the key properties, and the property tuple must be unique within the label.

CREATE CONSTRAINT FOR (p:Person) REQUIRE (p.first, p.last) IS NODE KEY;
CREATE (:Person {first: 'Ada', last: 'Lovelace'});
CREATE (:Person {first: 'Ada', last: 'Byron'});      // ok (different tuple)
CREATE (:Person {first: 'Ada', last: 'Lovelace'});   // error: duplicate node key
CREATE (:Person {first: 'Ada'});                     // error: missing key property

Element-uniqueness constraints

REQUIRE EACH n.prop IS UNIQUE is uniqueness per element: no other node with the label may hold any of this node's elements, in any position — but a node repeating its own element across slots is allowed (a staged id where draft == live is the steady state, not a violation).

CREATE CONSTRAINT FOR (u:User) REQUIRE EACH u.id IS UNIQUE;
CREATE (:User {id: ['xxx', null, 'xxx']});   // ok (own repeat)
CREATE (:User {id: [null, 'xxx', null]});    // error: element uniqueness violation
CREATE (:User {id: 'xxx'});                  // error (a scalar is one element)

It is backed by an element index (Element indexes and staged values): declaring the constraint auto-creates the index if absent, existing data is validated at declaration, and the backing index cannot be dropped while the constraint lives. SHOW CONSTRAINTS reports it as ELEMENT_UNIQUE.

Group- (multi-label) uniqueness constraints

A plain IS UNIQUE constraint is scoped to one label: a :User and a :Product may each hold id = 'x' independently. A label alternation (n:A|B|C) opts a set of labels into a shared uniqueness namespace — the value must be unique across the union of nodes carrying any of those labels (a Galactus DB extension).

CREATE CONSTRAINT FOR (n:Person|Company|Address) REQUIRE n.id IS UNIQUE;
CREATE (:Person  {id: 'x'});
CREATE (:Company {id: 'x'});   // error: group uniqueness violation
CREATE (:Vehicle {id: 'x'});   // ok: Vehicle was not opted in

Semantics:

  • Opt-in by label. Only the named labels participate; a label outside the group shares no namespace with it. A node with no property, or with the property but none of the group's labels, is unconstrained.

  • Own repeats are fine. One node carrying two of the group's labels (:Person:Company {id: 'x'}) posts the same value twice but is a single node, not a collision.

  • Gaining a label is checked. SET n:Company subjects n's existing properties to the group there and then.

  • Removal is automatic. Deleting the node, removing the property, or removing the group label frees the value immediately — enforcement fans across each label's index, so there is no separate structure to keep in sync.

  • Modifiable in place — CREATE adds, DROP removes. The group is keyed by the property, so the label set is edited without a rebuild. The verbs are asymmetric on purpose: CREATE never destroys, so re-running any old CREATE is safe.

    // add: union more labels in (revalidated; rejected if existing data collides)
    CREATE CONSTRAINT FOR (n:Person|Company|Vehicle) REQUIRE n.id IS UNIQUE;
    
    // remove: name the labels to opt out (relaxing, so never fails)
    DROP CONSTRAINT FOR (n:Vehicle)        REQUIRE n.id IS UNIQUE;  // {Person, Company}
    DROP CONSTRAINT FOR (n:Company|Vehicle) REQUIRE n.id IS UNIQUE; // removes both
    

    Re-declaring with a smaller set does not shrink the group (CREATE only ever unions — use DROP to remove). The group vanishes once its last label is removed. A removed label's backing index is left in place, and becomes eligible for DROP INDEX again. A single-label DROP … IS UNIQUE prefers a plain uniqueness constraint on that pair, and only removes the label from a group when no plain unique exists.

Each participating label gets a backing (label, id) hash index for free (auto-created, backfilled, and drop-protected while the constraint lives), so MATCH (p:Person {id: 'x'}) still seeks. Existing data is validated across the union at declaration. SHOW CONSTRAINTS reports it as GROUP_UNIQUE with the labels joined by |.

The alternation is valid only with a plain IS UNIQUE; IS NOT NULL, IS NODE KEY, and REQUIRE EACH … IS UNIQUE remain single-label.

SHOW CONSTRAINTS reports each constraint's type (UNIQUE, NODE_PROPERTY_EXISTENCE, NODE_KEY, ELEMENT_UNIQUE, GROUP_UNIQUE).

EXPLAIN and PROFILE · Resident and hybrid storage · Schema and maintenance procedures

Planning a deployment? Review compatibility and licence setup for your instance.