How to create unique CONSTRAINT to relationship by neo4j cypher?
-
Why am i ask this questions because I saw that (rest-api-unique-indexes)[http://docs.neo4j.org/chunked/stable/rest-api-unique-indexes.html] ,and thought that before I use this API should create uniqueness constraint at the node with a specific label,but i not find how to create uniqueness constraint at the relationship! Now I see that the 'unique relationship' can run well and need not constraint,maybe it use Create Unique! – Kail May 13 '14 at 02:04
6 Answers
At present, there is only one kind of CONSTRAINT
neo4j will let you create, and that's a UNIQUENESS constraint. That link cites what's in the internal API, and you'll notice there's only one type at present.
Here's a link on how to create a uniqueness constraint.
This lets you assert that a certain property of a node must be unique, but it doesn't say anything about relationships. I don't think it's possible to constrain what sort of relationships can come off of various nodes.

- 17,634
- 4
- 52
- 86
-
thanks!Why am i ask this questions because I saw that([rest-api-unique-indexes](http://docs.neo4j.org/chunked/stable/rest-api-unique-indexes.html)),and thought that before I use this API should create **uniqueness constraint** at the node with a specific label,but i not find how to create **uniqueness constraint** at the relationship([ create unique relationship](http://docs.neo4j.org/chunked/stable/rest-api-unique-indexes.html#rest-api-get-or-create-unique-relationship-create))! Now I see that the 'unique relationship' can run well and need not constraint,maybe it use `Create Unique`! – Kail May 13 '14 at 01:49
If I understood your problem correctly, you want to enforce uniqueness of certain kind of relation rather than uniqueness of relation's certain attribute. If that's what you want, then you enforce such uniqueness by using "CREATE UNIQUE":
MATCH (root { name: 'root' })
CREATE UNIQUE (root)-[:LOVES]-(someone)
RETURN someone

- 8,390
- 14
- 74
- 124

- 131
- 5
-
1Link is broken. Futhermore, it seems to me that CREATE UNIQUE is no more valid. – Alessandro Flati Oct 24 '17 at 14:11
-
@AlessandroFlati The link is back, and even though `CREATE_UNIQUE` is invalid you can use the valid `MERGE` alternatives that are listed in the `CREATE_UNIQUE` docs in the link. Note this is more a workaround as it doesn't actually create a constraint between a Node and relationship, but just allows you to create unique node relationship pairs at the query level. Which means you have to be weary of accidentally creating duplicate relationships that should be unique. – John Jan 10 '19 at 21:56
-
Specifically the relevant `MERGE` alternatives are in the Introduction section which should give you a pretty good idea of what to do. – John Jan 10 '19 at 21:58
it seems that a relationship constraint can only enforce the existence of a relationship property but not its uniqueness
CREATE CONSTRAINT ON ()-[like:LIKED]-() ASSERT exists(like.day)
http://neo4j.com/docs/developer-manual/current/cypher/#query-constraints-prop-exist-rels

- 2,552
- 1
- 22
- 28
Though you can't do this as a constraint just yet you can use the following work-around to get similar behavior at the query level (instead of the constraint level) by using MERGE
in your queries. You used to be able to use CREATE UNIQUE
to do this, but that has since been deprecated, but the CREATE UNIQUE
docs here have a good introduction section that covers the details pretty well and shows you how to do alternatively in the non-deprecated MERGE
way.
So, you can use these docs to see how you can create unique nodes and relationships through queries using MERGE
. Also, since this uniqueness is decided at the query level instead of the constraint level you should be very cautious of accidentally creating duplicate data where it should be unique.
(I'll put the current relevant doc sections provided above for CREATE UNIQUE
with the MERGE
alternatives here in case they disappear.)
CREATE UNIQUE
is in the middle ofMATCH
andCREATE
— it will match what it can, and create what is missing.We show in the following example how to express using
MERGE
the same level of uniqueness guaranteed byCREATE UNIQUE
for nodes and relationships.Assume the original set of queries is given by:
MERGE (p:Person {name: 'Joe'})
RETURN p
MATCH (a:Person {name: 'Joe'})
CREATE UNIQUE (a)-[r:LIKES]->(b:Person {name: 'Jill'})-[r1:EATS]->(f:Food {name: 'Margarita Pizza'})
RETURN a
MATCH (a:Person {name: 'Joe'})
CREATE UNIQUE (a)-[r:LIKES]->(b:Person {name: 'Jill'})-[r1:EATS]->(f:Food {name: 'Banana'})
RETURN a
This will create two
:Person
nodes, a:LIKES
relationship between them, and two:EATS
relationships from one of the:Person
nodes to two:Food
nodes. No node or relationship is duplicated.The following set of queries — using
MERGE
— will achieve the same result:
MERGE (p:Person {name: 'Joe'})
RETURN p
MATCH (a:Person {name: 'Joe'})
MERGE (b:Person {name: 'Jill'})
MERGE (a)-[r:LIKES]->(b)
MERGE (b)-[r1:EATS]->(f:Food {name: 'Margarita Pizza'})
RETURN a
MATCH (a:Person {name: 'Joe'})
MERGE (b:Person {name: 'Jill'})
MERGE (a)-[r:LIKES]->(b)
MERGE (b)-[r1:EATS]->(f:Food {name: 'Banana'})
RETURN a
We note that all these queries can also be combined into a single, larger query.
The
CREATE UNIQUE
examples below use the following graph:
--- source: Cypher Manual v3.5: Section 3.18, Introduction

- 7,114
- 2
- 37
- 57
As in Neo4j community edition version 2.3.1 there seems to be no constraints on relations.
neo4j-sh (?)$ schema ls
Indexes
ON :RELTYPE(id) ONLINE (for uniqueness constraint)
Constraints
ON (reltype:RELTYPE) ASSERT reltype.id IS UNIQUE
You can easily create multiple relations with of type RELTYPE and the same id globally or even between the same nodes
MATCH (s:Person {name:"foo"}), (t:Target {name:"target"})
CREATE (s)-[r:RELTYPE {id:"baz"}]-(t)
This constraint seems to be applied to node only , I can not find anything mentioning the relation in the neo4j documentation
http://neo4j.com/docs/stable/rest-api-schema-constraints.html

- 173
- 1
- 12
What I would like to see (but from my reading of the Neo4J documentation is not currently possible) is to constrain (for example) the ACTED_IN relationship:
(:Person)-[ACTED_IN]->(:Movie)
to prevent the erroneous relationship:
(:Movie)-[ACTED_IN]->(:Person)
Obviously, you can find the bad backwards relationships this way but it would be nice to prevent it from happening with a constraint:
match((m:Movie)-[:ACTED_IN]->(p:Person)) return m,p

- 689
- 8
- 14