有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Neo4j匹配。。。UPSERT的合并密码语法正在返回(无行)

我昨天刚开始用Neo4j学习GraphDB,现在,我想执行如下所示的UPSERT操作

match (circle:Circle {id:3, cycleId:5})
merge (member1:Member {id:1}) -[invited:INVITED_TO_JOIN {c:circle, time:timestamp()}]-> (member2:Member {id:2})
return member1, member2, invited, circle

根据此处的文档http://neo4j.com/docs/stable/query-merge.html如果具有指定属性的节点圆圈不存在,则应创建节点和指定的关系,否则,应更新节点和关系。然而,这并没有发生。我只收到一封信,上面写着(no rows)。见下文

enter image description here

有人能指出我可能做得不对的地方吗

编辑:但我想动态创建circlemember1member2它们之间的关系,而不必担心节点以前是否存在,但如果它们已经存在,只需相应地更新它们


编辑:在@DaveBennet@cybersam和@迈克尔亨格

主要目的:创建一种关系,意味着member1邀请member2加入circle3

  1. 如果节点/关系不存在,请创建它们
  2. 如果存在节点/关系,则更新它们

在所有情况下,任何节点或关系都不应重复

这不应该像现在这样困难。我真的开始觉得有些东西文档没有恰当地传达出来

另见此处:http://neo4j.com/docs/stable/query-create-unique.html

让我困惑的是,为什么在match...merge/match...create unique查询返回行之前必须有一个精确的节点-匹配?这不是违背了查询本身的目的吗?。。。特别是在创建方面

我甚至创建了一个节点,如下所示

create (member:Member) return member

然后尝试了下面的查询-非常清楚地知道member节点现在已经存在,但没有任何属性(例如id,如下所示)

match (member:Member {id:1})
create unique (member) -[memberOf:IS_MEMBER_OF {time:timestamp()}]-> (circle:Circle {id:3, cycleId:5, creator:member.id}) 
return member, circle, memberOf

我认为这应该搜索id=1的成员节点。。。这是不存在的,因此它应该继续创建新的member节点,并使用它的属性、定义的关系以及任何其他必需的节点

令我惊讶的是,这仍然返回(没有行)

因此,如果有人指点我实现既定目标,向我清楚地解释为什么我所尝试的不会奏效,以及为什么建议的解决方案会奏效,我将不胜感激

谢谢


共 (2) 个答案

  1. # 1 楼答案

    MATCH子句仅在匹配时成功,如果不匹配,则中止整个查询^另一方面,{}从不中止查询(并为任何不匹配的项提供NULL值)

    不幸的是,MERGE子句不支持节点具有@MichaelHunger建议答案中的invite节点所需的3种关系的模式。这是因为一个模式每个节点只能表示2个关系,并且MERGE不接受多个(逗号分隔的)模式

    此查询使用类似于@MichaelHunger的数据模型,可能适用于您:

    MERGE (circle:Circle { id:3, cycleId:5 })
    MERGE (member1:Member { id:1 })
    MERGE (member2:Member { id:2 })
    WITH circle, member1, member2
    OPTIONAL MATCH (member1)<-[:INVITED_BY]-(invite:Invite)-[:INVITED]->(member2), (invite)-[:TO_CIRCLE]->(circle)
    WITH circle, member1, member2,
      CASE
        WHEN invite IS NULL THEN [1]
        ELSE NULL END AS doit
    FOREACH (ignored IN doit | 
      CREATE (i:Invite { time:timestamp()})-[:TO_CIRCLE]->(circle),(member1)<-[:INVITED_BY]-(i)-[:INVITED]->(member2))
    WITH circle, member1, member2
    MATCH (member1)<-[:INVITED_BY]-(invite:Invite)-[:INVITED]->(member2), (invite)-[:TO_CIRCLE]->(circle)
    RETURN member1, member2, invite, circle;
    

    这个查询使用了一个方便但棘手的变通方法,涉及OPTIONAL MATCHCASEFOREACH子句

    需要使用末尾的MATCH重新找到正确的Invite节点,以便查询可以返回它,因为在FOREACH子句中定义的任何标识符在该子句之外都是不可见的

  2. # 2 楼答案

    你很可能想通过一个邀请节点连接这两个成员

    match (circle:Circle {id:3, cycleId:5})
    match (member1:Member {id:1})
    match (member2:Member {id:2})
    create (invite:Invite {time:timestamp()})-[:TO_CIRCLE]->(circle)
    create (invite)-[:INVITED_BY]->(member1)
    create (invite)-[:INVITED]->(member2)
    return member1, member2, invite, circle;
    

    否则,如果您只想记录事实:

    match (circle:Circle {id:3, cycleId:5})
    match (member1:Member {id:1})
    match (member2:Member {id:2})
    merge (member1)-[r:MEMBER]->(circle)
    on create set r.since = timestamp(), r.by = member2.id