你能为neo4j中属于两个标签的所有节点之间的关系创建一个唯一性约束吗?

时间:2018-05-07 17:10:39

标签: neo4j cypher

我有以下标签:

  • (:Product)
  • (:Brand)

他们的关系如下:

  • (:Product)-[:is_of]->(:Brand)

例如,如果以下查询运行两次,它将成功。

CREATE (:Product { name: "Chocolate"})-[:is_of]->(:Brand {name: "Cadbury"})

以下查询的图表结果可以在图片here

中看到
MATCH (p:Product { name: "Chocolate"})-[:is_of]->(b:Brand {name: "Cadbury"}) RETURN p,b 

正如您所看到的,有2个“巧克力”产品节点和2个“吉百利”品牌节点。

我想强制执行一项,在创建产品时,只有一个产品节点的属性name = "Chocolate"与属性is_of的品牌有name = "Cadbury"关系。因此,上述CREATE查询将在第二次尝试时失败,并显示一些消息:There is already one product node with a name = "Chocolate" and a brand of "Cadbury". This is prohibited by a constraint

关系数据库模拟将是一个延伸多个外键的主键。例如,将以下内容添加到表Product,其中表Brand具有主键Brand ID

PRIMARY KEY("Product ID","Brand ID")

我尝试对品牌的财产设置限制,只允许使用独特的品牌。但问题是你仍然可以创建两个is_of同一品牌的产品。我不想在产品name上创建一个独特的约束,因为可能有来自不同品牌的多个“巧克力”产品。

我已经阅读了文档,但似乎约束只能放在属性上......

我会想象语法如下所示:

CREATE CONSTRAINT ON g=(p:Product)-[:is_of]->(b:Brand) ASSERT g IS UNIQUE FOR p.name, b.name

2 个答案:

答案 0 :(得分:1)

简短的回答是否。

有人谈到在Neo中为约束设置任意模式语法,但它还没有,或者在路线图上,AFIAK。我在野外发现的最接近的是一个非官方的回购中的未合并的CIP:
https://github.com/Mats-SX/openCypher/blob/88c0f11f11410ce2f68dc050e54ff419058c6cad/cip/1.accepted/CIP2016-12-14-Constraint-syntax.adoc

请参阅当前可用约束语法的文档:
https://neo4j.com/docs/developer-manual/current/cypher/schema/constraints/

我认为,3.3.x中最接近的是将:is_of关系转换为一个节点,并在其上放置一个可以创建节点密钥的属性。

答案 1 :(得分:0)

在此较旧的线程中添加更新,因为它带有约束搜索结果。

您要执行的操作需要企业许可证。拥有企业许可证时,可以对路径()-[]-()实施约束。您还可以使用具有多个属性的方案。

作为一个仅供参考,我想反过头来,因为恕我直言,品牌与他们的产品有着(直接的)关系。它也可以使非企业版本的约束更容易实现。只是一个想法。