我想在我的数据库中的节点上添加“创建者”关系。任何节点都应该能够建立这种关系,但永远不会有多个节点。
现在我的查询看起来像这样:
MATCH (u:User {email: 'my@mail.com'})
MERGE (n:Node {name: 'Node name'})
ON CREATE SET n.name='Node name', n.attribute='value'
CREATE UNIQUE (n)-[:CREATED_BY {date: '2015-02-23'}]->(u)
RETURN n
由于我已经了解Cypher没有办法实现我想要的,当前的查询只会确保没有基于TWO节点的唯一关系,而不是ONE。因此,当为另一个用户运行时,这将创建更多的CREATED_BY关系,并且我希望将传出的CREATED_BY关系限制为仅适用于所有节点的关系。
有没有办法在不运行涉及程序逻辑的多个查询的情况下实现这一目标?
感谢。
更新
我尝试通过删除实现细节来简单地查询查询,如果它有助于此处基于cybersams响应的更新查询。
MERGE (c:Company {name: 'Test Company'})
ON CREATE SET c.uuid='db764628-5695-40ee-92a7-6b750854ebfa', c.created_at='2015-02-23 23:08:15', c.updated_at='2015-02-23 23:08:15'
WITH c
OPTIONAL MATCH (c)
WHERE NOT (c)-[:CREATED_BY]-()
CREATE (c)-[:CREATED_BY {date: '2015-02-23 23:08:15'}]->(u:User {token: '32ba9d2a2367131cecc53c310cfcdd62413bf18e8048c496ea69257822c0ee53'})
RETURN c
仍未按预期工作。
更新#2
我最终将此分为两个查询。
我发现的问题是我注意到有两种可能的结果。
CREATED_BY
关系已创建,(n)
已使用OPTIONAL MATCH
返回,如果(n)
与(u)
之间尚未存在,则始终会创建此关系(n)
,因此在更改电子邮件属性时,它会重新创建关系。
找不到节点OPTIONAL MATCH
(因为没有使用WHERE NOT (c)-[:CREATED_BY]-()
和(n)
子句),导致没有创建任何关系(是的!)但没有获得{ {1}} {}回复MERGE
查询失去了我想的所有意思。
我的解决方案是以下两个查询:
MERGE (n:Node {name: 'Name'})
ON CREATE SET
SET n.attribute='value'
WITH n
OPTIONAL MATCH (n)-[r:CREATED_BY]-()
RETURN c, r
然后我让程序逻辑检查r
的值,如果没有关系,我会运行第二个查询。
MATCH (n:Node {name: 'Name'})
MATCH (u:User {email: 'my@email.com'})
CREATE UNIQUE (n)-[:CREATED_BY {date: '2015-02-23'}]->(u)
RETURN n
不幸的是,我找不到任何真正的解决方案,可以在一个查询中与Cypher结合使用。山姆,谢谢!我已经选择了你的答案,即使它没有完全解决我的问题,但它非常接近。
答案 0 :(得分:2)
这应该适合你:
MERGE (n:Node {name: 'Node name'})
ON CREATE SET n.attribute='value'
WITH n
OPTIONAL MATCH (n)
WHERE NOT (n)-[:CREATED_BY]->()
CREATE UNIQUE (n)-[:CREATED_BY {date: '2015-02-23'}]->(:User {email: 'my@mail.com'})
RETURN n;
我已删除了起始MATCH
子句(因为我认为即使数据库中尚不存在CREATED_BY
,您也希望创建User
关系,并且简化了ON CREATE
以删除name
属性的冗余设置。
我还添加了一个OPTIONAL MATCH
,它只匹配一个尚未传出n
关系的CREATED_BY
节点,后跟一个完全指定的CREATE UNIQUE
子句User
节点。