如何使用Neo4j Cypher创建唯一约束条件以建立关系?

6个回答

5
目前,Neo4j只支持创建一种约束:CONSTRAINT,并且这是唯一的类型:UNIQUENESS 约束。该链接引用了内部API的内容,您会发现目前只有一种类型。

这里有一个创建唯一性约束的链接

这使您可以断言节点的某个属性必须是唯一的,但它不涉及关系。我认为不可能限制各种节点的关系。


为什么我会问这个问题呢?因为我看到了(rest-api-unique-indexes),并且认为在使用此API之前应该在具有特定标签的节点上创建唯一性约束,但我没有找到如何在关系中创建唯一性约束create unique relationship)!现在我发现“唯一关系”可以正常运行而不需要约束,也许它使用了Create Unique - Kail

4

如果我正确理解了您的问题,您想强制执行某种关系的唯一性,而不是关系某个属性的唯一性。如果这就是您想要的,那么您可以使用“CREATE UNIQUE”来强制实现这种唯一性:

MATCH (root { name: 'root' })
CREATE UNIQUE (root)-[:LOVES]-(someone)
RETURN someone

Neo4j手册:创建独特的关系


1
链接已损坏。此外,我认为CREATE UNIQUE不再有效。 - Alessandro Flati
@AlessandroFlati 链接已恢复,尽管 CREATE_UNIQUE 无效,但您可以使用链接中列出的有效的 MERGE 替代方案。请注意,这更像是一种解决方法,因为它实际上并没有在节点和关系之间创建约束,而只是允许您在查询级别创建唯一的节点关系对。这意味着您必须小心不要意外创建应该是唯一的重复关系。 - John
具体来说,相关的“MERGE”替代方案在介绍部分中,这应该会给你一个很好的想法。 - John

3

2
尽管您目前无法将此作为约束条件执行,但可以使用以下解决方法在查询级别(而不是约束级别)使用MERGE来获得类似的行为。过去您可以使用CREATE UNIQUE来实现这一点,但现在已被弃用,但是CREATE UNIQUE文档here有一个很好的介绍部分,涵盖了详细信息并展示了如何使用非弃用的MERGE方式进行替代。
因此,您可以使用这些文档来查看如何通过使用MERGE在查询中创建唯一节点和关系。此外,由于这种唯一性是在查询级别而不是约束级别上决定的,因此您应该非常小心,以免在本应是唯一的地方意外创建重复数据。
(我将上面提供的与当前相关的CREATE UNIQUE文档部分及MERGE替代方法放在这里,以防它们消失。)
"CREATE UNIQUE"位于"MATCH"和"CREATE"之间——它会匹配已有的内容,并创建缺失的内容。下面的示例展示了如何使用"MERGE"来表达与"CREATE UNIQUE"相同的节点和关系唯一性级别。假设原始查询集合如下:
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

这将创建两个“:Person”节点,它们之间有一个“:LIKES”关系,并且从其中一个“:Person”节点到两个“:Food”节点有两个“:EATS”关系。没有节点或关系被重复创建。
以下一组使用“MERGE”的查询也能达到同样的结果:
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

我们注意到所有这些查询也可以组合成一个更大的查询。下面的`CREATE UNIQUE`示例使用以下图表:

enter image description here

--- 来源:Cypher 手册 v3.5:第 3.18 节,介绍

1

在Neo4j社区版2.3.1中,似乎没有关系上的约束。


   neo4j-sh (?)$ schema ls
Indexes
  ON :RELTYPE(id)  ONLINE (for uniqueness constraint)
Constraints
  ON (reltype:RELTYPE) ASSERT reltype.id IS UNIQUE

你可以轻松地创建多个类型为RELTYPE且具有相同id的关系,无论是全局还是在相同节点之间。
MATCH (s:Person {name:"foo"}),  (t:Target {name:"target"})
CREATE  (s)-[r:RELTYPE {id:"baz"}]-(t)

这个约束似乎只适用于节点,我在Neo4j文档中没有找到任何提到这种关系的内容。

http://neo4j.com/docs/stable/rest-api-schema-constraints.html


0

我希望看到的(但根据我阅读的Neo4J文档,目前不可能)是限制(例如)ACTED_IN关系:

(:Person)-[ACTED_IN]->(:Movie)

以防止错误的关系:

(:Movie)-[ACTED_IN]->(:Person)

显然,你可以通过这种方式找到错误的反向关系,但最好通过约束来防止它发生:

match((m:Movie)-[:ACTED_IN]->(p:Person)) return m,p


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接