13

How to create unique CONSTRAINT to relationship by neo4j cypher?

Kail
  • 155
  • 1
  • 1
  • 5
  • 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 Answers6

5

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.

FrobberOfBits
  • 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
4

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

The Neo4j Manual: Create unique relationships

roschach
  • 8,390
  • 14
  • 74
  • 124
ikolomiets
  • 131
  • 5
  • 1
    Link 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
3

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

Albert S
  • 2,552
  • 1
  • 22
  • 28
2

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 of MATCH and CREATE — 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 by CREATE 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:

enter image description here

--- source: Cypher Manual v3.5: Section 3.18, Introduction

John
  • 7,114
  • 2
  • 37
  • 57
1

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

maryoush
  • 173
  • 1
  • 12
0

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

Clem Wang
  • 689
  • 8
  • 14