创建cypher语句,用于创建或更新已存在(或不存在)的关系和道具

时间:2015-09-21 16:05:31

标签: neo4j cypher

我正在尝试创建一个chyper声明:

  1. 如果两个节点之间不存在关系,我就创建它
  2. 修改其中的属性。
  3. 所以我想出了这个:

    String modifyRelations="match (p1:User),(p2:User) " +
                        "WHERE p1.userId=~{1} and p2.userId=~{2} "+
                        "MERGE (p1)-[r:follow]->(p2)"+
                        "SET follow.followType={3}";
    
    
            final PreparedStatement ps1 = conn.prepareStatement(modifyRelations);
                ps1.setString(1, sourceNodeDTO.getUserId());
                ps1.setString(2, targetNodeDTO.getUserId());
                ps1.setString(3, followTypes.getValue());
    

    我收到了错误:

    Neo.ClientError.Statement.InvalidSyntax, message=follow not defined
    

    事情是,我不想创建新的关系,以防它已经存在。

    如果存在,我只想修改其中的属性(follow)。 但如果关系不存在,我想创建它并将其设置为follow属性

    谢谢你, 射线。

2 个答案:

答案 0 :(得分:1)

[增订]

回答原始问题

绝对需要更改的唯一内容就是您的SET子句。它需要通过标识符(r)引用关系,而不是它的关系类型:

"SET r.followType={3}";

MERGE子句仅在匹配的followp1节点之间创建新的p2关系(如果尚不存在)。它将匹配(而不是创建)现有的follow关系,即使它具有其他属性键/值。

但是, 也应该更改WHERE子句,因为正则表达式对您没有任何作用,直接字符串比较也不会。在Cypher中,正则表达式匹配整个值,并且由于您的正则表达式不使用通配符且不区分大小写,因此您应该使用简单的字符串比较。正则表达式也比简单的字符串比较慢。

String modifyRelations=
    "MATCH (p1:User), (p2:User) " +
    "WHERE p1.userId={1} and p2.userId={2} "+
    "MERGE (p1)-[r:follow]->(p2)"+
    "SET r.followType={3}";

回答评论中的问题

要在以下评论中回答您的后续问题,此查询还会创建p1和/或p2(如果尚不存在):

String modifyRelations=
    "MERGE (p1:User {userId: {1}})" +
    "MERGE (p2:User {userId: {2}})" +
    "MERGE (p1)-[r:follow]->(p2)"+
    "SET follow.followType={3}";

答案 1 :(得分:0)

您混合了变量/标识符(在您的情况下为r)和关系类型follow

优良做法是全部限制rel-type,然后更明显。

即。 FOLLOWS

MATCH (p1:User),(p2:User)
WHERE p1.userId=~{1} and p2.userId=~{2} 
MERGE (p1)-[r:FOLLOW]->(p2)
ON CREATE SET SET r.followType={3}

可能想要使用ON CREATE SET而不是简单的无条件SET