Neo4j 避免为每个匹配创建多个关系
我有以下模型,每个Neo4j 避免为每个匹配创建多个关系,neo4j,cypher,Neo4j,Cypher,我有以下模型,每个用户都链接到几个注释节点,具有编写的关系,每个注释都有一个flair属性,每个注释上的属性可能不同。我还有一个Flair节点,希望在User节点和Flair节点之间创建新的关系 +--------+ +---------+ | | | | | User +------+ REL:AUTHORED+-----+ Comment | |
用户
都链接到几个注释
节点,具有编写的
关系,每个注释都有一个flair
属性,每个注释上的属性可能不同。我还有一个Flair
节点,希望在User
节点和Flair
节点之间创建新的关系
+--------+ +---------+
| | | |
| User +------+ REL:AUTHORED+-----+ Comment |
| | | |
+--------+ +---------+
因此,我编写了下面的查询来尝试这样做,但它为每个具有正确天赋的注释节点从用户
节点生成了一个关系。我只想要这些节点之间的单一关系。我如何做到这一点
MATCH (a:User)-[:AUTHORED]-(c:Comment),(b:Flair)
WHERE c.flair = 'foo' and b.name = 'foo'
CREATE (a)-[r:VOTES_FOR]->(b)
RETURN type(a,b,r)
您希望使用MERGE
而不是CREATE
在这些节点之间只有一个关系
MATCH (a:User)-[:AUTHORED]-(c:Comment),(b:Flair)
WHERE c.flair = 'foo' and b.name = 'foo'
MERGE (a)-[r:VOTES_FOR]->(b)
RETURN type(a,b,r)
为避免创建重复关系,应使用而不是CREATE
:
MATCH (a:User)-[:AUTHORED]->(c:Comment), (b:Flair)
WHERE c.flair = 'foo' AND b.name = 'foo'
MERGE (a)-[r:VOTES_FOR]->(b)
RETURN a, b, r
此查询还删除了TYPE
函数的使用,因为您的查询非法使用它
但我也应该注意到,您通过为
关系添加投票,将冗余数据引入数据库。相反,我建议从Comment
节点中删除flair
属性,并将其替换为Comment
和flair
节点之间的关系。下面的查询应该可以实现这一点(并且还可以避免在多个位置重复存储相同的信息)。此外,它还处理所有flair值(不仅仅是“foo”):
或者,更有效地说,如果您真的不需要返回用户
:
MATCH (c:Comment), (f:Flair)
WHERE c.flair = f.name
REMOVE c.flair
MERGE (c)-[:FOR_FLAIR]->(f)
RETURN c, f
有了这个新的数据模型,您可以通过以下方式找到用户编写的所有不同天赋:
MATCH (user:User)-[:AUTHORED]->()-[:FOR_FLAIR]->(flair)
WHERE user.id = 123
RETURN user, COLLECT(DISTINCT flair) AS flairs
MATCH (user:User)-[:AUTHORED]->()-[:FOR_FLAIR]->(flair)
WHERE user.id = 123
RETURN user, COLLECT(DISTINCT flair) AS flairs