在节点类型 a 与其他两种节点类型 neo4j 中的任何一种之间建立关系

create a relationship between node type a to either of two other node types neo4j

目标是在一个查询中指向两个其他不同节点类型的关系。应该可行...

MATCH (a:person), (b:fruit|b:vegetable)
WHERE a.favorite_food = b.name
CREATE (a)-[r:likes]->(b)

这是我认为的样子,但似乎行不通?

谢谢!

如果我理解您要实现的目标,最简单的解决方案是向所有 Fruit 和 Vegetable 节点添加一个额外的 Food 标签。然后你有办法用一个标签来解决这两个问题,(b:Food)。

如果您不想这样做,可以使用 LABELS() 函数检查每个节点上是否存在特定标签。但是正如其他人所提到的,这将需要扫描数据库中的所有节点。

另一个解决方案是按顺序进行检查,但在移动到下一个之前使用聚合函数折叠查询管道(以避免笛卡尔积或必须收集不同的节点。

您需要一个迁移脚本来根据现有节点的属性添加 Neo4j 关系。我建议使用您选择的语言在通过适当的驱动程序调用 Neo4j 数据库的代码中编写迁移脚本。

不知道我是否完全理解你的问题。

如果您希望 (b) 与具有 fruit vegetable 标签的节点匹配,您可以使用 labels() function in conjunction with ANY .

MATCH (a:person), (b)
WHERE ANY(x IN ['fruit', 'vegetable'] WHERE x IN labels(b)) 
AND a.favorite_food = b.name
CREATE (a)-[r:likes]->(b)

如果您希望 (b) 与具有 fruit XOR vegetable 标签的节点匹配(即:一个且只有一个这两个标签),从 any() 更改为 single().

但是如果您希望 (b) 与具有 fruit AND vegetable 标签的节点匹配,您可以简单地指定两个标签匹配时使用相同的变量,如下所示:

MATCH (a:person), (b:fruit:vegetable)
WHERE a.favorite_food = b.name
CREATE (a)-[r:likes]->(b)

除了 Brunos ,您还可以使用

MATCH (a:Person) 
OPTIONAL MATCH (f:fruit), (v:vegetable) 
WITH m, COLLECT(DISTINCT f)+COLLECT(DISTINCT v) as list
UNWIND list as b
CREATE UNIQUE (a)-[r:likes]->(b)

MATCH (a:Person) 
OPTIONAL MATCH (f:fruit)
CREATE UNIQUE (a)-[r:likes]->(f)
WITH a
OPTIONAL MATCH (v:vegetable)
CREATE UNIQUE (a)-[r:likes]->(v)

根据您的数据库,这可能会更高效,因为它不需要全节点扫描。