Constraints
Introduction
The following constraint types are available:
- Unique property constraints
-
Unique property constraints ensure that property values are unique for all nodes with a specific label. Unique constraints do not mean that all nodes have to have a unique value for the properties — nodes without the property are not subject to this rule.
- Property existence constraints
-
Property existence constraints ensure that a property exists for all nodes with a specific label or for all relationships with a specific type. All queries that try to create new nodes or relationships without the property, or queries that try to remove the mandatory property will now fail.
- Node Keys
-
Node Keys ensure that, for a given label and set of properties:
-
All the properties exist on all the nodes with that label.
-
The combination of the property values is unique.
Queries attempting to do any of the following will fail:
-
Create new nodes without all the properties or where the combination of property values is not unique.
-
Remove one of the mandatory properties.
-
Update the properties so that the combination of property values is no longer unique.
-
| Property existence constraints and Node Keys are only available in Neo4j Enterprise Edition. Note that databases with property existence constraints and/or Node Keys cannot be opened using Neo4j Community Edition. |
A given label can have multiple constraints, and unique and property existence constraints can be combined on the same property.
Adding constraints is an atomic operation that can take a while — all existing data has to be scanned before Neo4j can turn the constraint 'on'.
Creating a constraint has the following implications on indexes:
-
Adding a unique property constraint on a property will also add a single-property index on that property, so such an index cannot be added separately.
-
Adding a Node Key for a set of properties will also add a composite index on those properties, so such an index cannot be added separately.
-
Cypher® will use these indexes for lookups just like other indexes; see the Indexes section for more details on the rules governing their behavior.
-
If a unique property constraint is dropped and the single-property index on the property is still required, the index will need to be created explicitly.
-
If a Node Key is dropped and the composite-property index on the properties is still required, the index will need to be created explicitly.
Create unique constraint
To create a constraint that makes sure that your database will never contain more than one node with a specific label and one property value, use the IS UNIQUE syntax.
CREATE CONSTRAINT ON (book:Book) ASSERT book.isbn IS UNIQUE
+-------------------+
| No data returned. |
+-------------------+
Unique constraints added: 1
Drop unique constraint
By using DROP CONSTRAINT, you remove a constraint from the database.
DROP CONSTRAINT ON (book:Book) ASSERT book.isbn IS UNIQUE
+-------------------+
| No data returned. |
+-------------------+
Unique constraints removed: 1
Create a node that complies with unique property constraints
Create a Book node with an isbn that isn’t already in the database.
CREATE (book:Book { isbn: '1449356265', title: 'Graph Databases' })
+-------------------+
| No data returned. |
+-------------------+
Nodes created: 1
Properties set: 2
Labels added: 1
Create a node that violates a unique property constraint
Create a Book node with an isbn that is already used in the database.
CREATE (book:Book { isbn: '1449356265', title: 'Graph Databases' })
In this case the node isn’t created in the graph.
Node(0) already exists with label `Book` and property `isbn` = '1449356265'
Failure to create a unique property constraint due to conflicting nodes
Create a unique property constraint on the property isbn on nodes with the Book label when there are two nodes with the same isbn.
CREATE CONSTRAINT ON (book:Book) ASSERT book.isbn IS UNIQUE
In this case the constraint can’t be created because it is violated by existing data. We may choose to use Indexes instead or remove the offending nodes and then re-apply the constraint.
Unable to create CONSTRAINT ON ( book:Book ) ASSERT book.isbn IS UNIQUE:
Both Node(0) and Node(20) have the label `Book` and property `isbn` =
'1449356265'
Get a list of all constraints in the database
Calling the built-in procedure db.constraints will list all the constraints in the database.
CALL db.constraints
+----------------------------------------------------------+
| description |
+----------------------------------------------------------+
| "CONSTRAINT ON ( book:Book ) ASSERT book.isbn IS UNIQUE" |
+----------------------------------------------------------+
1 row
Create node property existence constraint
To create a constraint that ensures that all nodes with a certain label have a certain property, use the ASSERT exists(variable.propertyName) syntax.
CREATE CONSTRAINT ON (book:Book) ASSERT exists(book.isbn)
+-------------------+
| No data returned. |
+-------------------+
Property existence constraints added: 1
Drop node property existence constraint
By using DROP CONSTRAINT, you remove a constraint from the database.
DROP CONSTRAINT ON (book:Book) ASSERT exists(book.isbn)
+-------------------+
| No data returned. |
+-------------------+
Property existence constraints removed: 1
Create a node that complies with property existence constraints
Create a Book node with an isbn property.
CREATE (book:Book { isbn: '1449356265', title: 'Graph Databases' })
+-------------------+
| No data returned. |
+-------------------+
Nodes created: 1
Properties set: 2
Labels added: 1
Create a node that violates a property existence constraint
Trying to create a Book node without an isbn property, given a property existence constraint on :Book(isbn).
CREATE (book:Book { title: 'Graph Databases' })
In this case the node isn’t created in the graph.
Node(0) with label `Book` must have the property `isbn`
Removing an existence constrained node property
Trying to remove the isbn property from an existing node book, given a property existence constraint on :Book(isbn).
MATCH (book:Book { title: 'Graph Databases' })
REMOVE book.isbn
In this case the property is not removed.
Node(0) with label `Book` must have the property `isbn`
Failure to create a node property existence constraint due to existing node
Create a constraint on the property isbn on nodes with the Book label when there already exists a node without an isbn.
CREATE CONSTRAINT ON (book:Book) ASSERT exists(book.isbn)
In this case the constraint can’t be created because it is violated by existing data. We may choose to remove the offending nodes and then re-apply the constraint.
Unable to create CONSTRAINT ON ( book:Book ) ASSERT exists(book.isbn):
Node(0) with label `Book` must have the property `isbn`
Create relationship property existence constraint
To create a constraint that makes sure that all relationships with a certain type have a certain property, use the ASSERT exists(variable.propertyName) syntax.
CREATE CONSTRAINT ON ()-[like:LIKED]-() ASSERT exists(like.day)
+-------------------+
| No data returned. |
+-------------------+
Property existence constraints added: 1
Drop relationship property existence constraint
To remove a constraint from the database, use DROP CONSTRAINT.
DROP CONSTRAINT ON ()-[like:LIKED]-() ASSERT exists(like.day)
+-------------------+
| No data returned. |
+-------------------+
Property existence constraints removed: 1
Create a relationship that complies with property existence constraints
Create a LIKED relationship with a day property.
CREATE (user:User)-[like:LIKED { day: 'yesterday' }]->(book:Book)
+-------------------+
| No data returned. |
+-------------------+
Nodes created: 2
Relationships created: 1
Properties set: 1
Labels added: 2
Create a relationship that violates a property existence constraint
Trying to create a LIKED relationship without a day property, given a property existence constraint :LIKED(day).
CREATE (user:User)-[like:LIKED]->(book:Book)
In this case the relationship isn’t created in the graph.
Relationship(0) with type `LIKED` must have the property `day`
Removing an existence constrained relationship property
Trying to remove the day property from an existing relationship like of type LIKED, given a property existence constraint :LIKED(day).
MATCH (user:User)-[like:LIKED]->(book:Book)
REMOVE like.day
In this case the property is not removed.
Relationship(0) with type `LIKED` must have the property `day`
Failure to create a relationship property existence constraint due to existing relationship
Create a constraint on the property day on relationships with the LIKED type when there already exists a relationship without a property named day.
CREATE CONSTRAINT ON ()-[like:LIKED]-() ASSERT exists(like.day)
In this case the constraint can’t be created because it is violated by existing data. We may choose to remove the offending relationships and then re-apply the constraint.
Unable to create CONSTRAINT ON ()-[ liked:LIKED ]-() ASSERT exists(liked.day):
Relationship(0) with type `LIKED` must have the property `day`
Create a Node Key
To create a Node Key ensuring that all nodes with a particular label have a set of defined properties whose combined value is unique, and where all properties in the set are present, use the ASSERT (variable.propertyName_1, …, variable.propertyName_n) IS NODE KEY syntax.
CREATE CONSTRAINT ON (n:Person) ASSERT (n.firstname, n.surname) IS NODE KEY
+-------------------+
| No data returned. |
+-------------------+
Node key constraints added: 1
Drop a Node Key
Use DROP CONSTRAINT to remove a Node Key from the database.
DROP CONSTRAINT ON (n:Person) ASSERT (n.firstname, n.surname) IS NODE KEY
+-------------------+
| No data returned. |
+-------------------+
Node key constraints removed: 1
Create a node that complies with a Node Key
Create a Person node with both a firstname and surname property.
CREATE (p:Person { firstname: 'John', surname: 'Wood', age: 55 })
+-------------------+
| No data returned. |
+-------------------+
Nodes created: 1
Properties set: 3
Labels added: 1
Create a node that violates a Node Key
Trying to create a Person node without a surname property, given a Node Key on :Person(firstname, surname), will fail.
CREATE (p:Person { firstname: 'Jane', age: 34 })
In this case the node isn’t created in the graph.
Node(0) with label `Person` must have the properties `firstname, surname`
Removing a NODE KEY-constrained property
Trying to remove the surname property from an existing node Person, given a NODE KEY constraint on :Person(firstname, surname).
MATCH (p:Person { firstname: 'John', surname: 'Wood' })
REMOVE p.surname
In this case the property is not removed.
Node(0) with label `Person` must have the properties `firstname, surname`
Failure to create a Node Key due to existing node
Trying to create a Node Key on the property surname on nodes with the Person label will fail when a node without a surname already exists in the database.
CREATE CONSTRAINT ON (n:Person) ASSERT (n.firstname, n.surname) IS NODE KEY
In this case the Node Key can’t be created because it is violated by existing data. We may choose to remove the offending nodes and then re-apply the constraint.
Unable to create CONSTRAINT ON ( person:Person ) ASSERT exists(person.firstname,
person.surname):
Node(0) with label `Person` must have the properties `firstname, surname`