Pergunta

How to create unique CONSTRAINT to relationship by neo4j cypher?

Foi útil?

Solução

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.

Outras dicas

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

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

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

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

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

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top