【问题标题】:Cypher: Adding properties to relationship as distinct valuesCypher:将属性添加到关系中作为不同的值
【发布时间】:2018-05-14 18:15:02
【问题描述】:

我要做的是编写一个查询 - 我已经将它设为一个 web 服务(在本地机器上工作,所以我将名称和人员作为参数) - 它连接具有相同爱好的人并设置hobbies 作为关系属性作为数组。 我的第一次尝试是;

MERGE (aa:Person{name:$name})
WITH aa, $people as people
FOREACH (person IN people |
MERGE (bb:Person{name:person.name})
MERGE (bb)-[r:SHARESSAMEHOBBY]->(aa)
ON MATCH SET r.hobbies = r.hobbies + person.hobby
ON CREATE SET r.hobbies = [person.hobby])

但是这会导致重复的属性元素,例如 ["swimming","swimming"]

我正在尝试仅设置唯一属性。然后我尝试了以下查询;

MERGE (aa:Person{name:$name})
WITH aa, $people as people FOREACH (person IN people | MERGE (bb:Person{name:person.name}) MERGE (bb)-[r:SHARESSAMEHOBBY]->(aa)
WITH r, COALESCE(r.hobbies, []) + person.hobby AS hobbies
UNWIND hobbies as unwindedHobbies
WITH r, collect(distinct, unwindedHobbies) AS unique
set r.as = unique)

但是现在它给了我语法错误;

 errorMessage = "[Neo.ClientError.Statement.SyntaxError] Invalid use of WITH inside FOREACH

感谢任何帮助。

【问题讨论】:

    标签: neo4j cypher


    【解决方案1】:

    这应该可行:

    MERGE (aa:Person {name: $name})
    WITH aa
    UNWIND $people AS person
    MERGE (bb:Person {name: person.name})
    MERGE (bb)-[r:SHARESSAMEHOBBY]-(aa)
    WITH r, person, CASE
      WHEN NOT EXISTS(r.hobbies) THEN {new: true}
      WHEN NOT (person.hobby IN r.hobbies) THEN {add: true}
      END AS todo
    FOREACH(ignored IN todo.new | SET r.hobbies = [person.hobby])
    FOREACH(ignored IN todo.add | SET r.hobbies = r.hobbies + person.hobby);
    

    您实际上有 2 个问题,上述查询解决了这两个问题:

    1. 如果SHARESSAMEHOBBY 关系已经存在于相反方向(从aabb),则以下MERGE 子句将导致不必要地创建第二个SHARESSAMEHOBBY 关系(从bbaa):

      合并 (bb)-[r:SHARESSAMEHOBBY]->(aa)

      为避免这种情况,您应该使用无方向关系模式(MERGE 允许,但CREATE 不允许)来匹配任一方向的关系,如下所示:

      合并 (bb)-[r:SHARESSAMEHOBBY]-(aa)

    2. 您需要确定是否有必要初始化一个新的hobbies 列表或将person.hobby 值添加到尚无该值的现有r.hobbies 列表中。上面的查询使用CASE 子句将NULL 或带有一个键的映射分配给todo,该键指示要执行哪些额外工作。然后,它使用FOREACH 子句酌情执行每件事。

    【讨论】:

    • 当我尝试它时,它说 [Neo.ClientError.Statement.SyntaxError] Invalid input 'S': expected 'l/L' ,有什么想法吗?
    • 我在测试我的答案时没有遇到语法错误。您显然有错字或其他语法错误(例如,您是否在正确的地方使用了WITH?)。在 Cypher 查询中哪里发现了错误?
    • 我发现了问题;我错过了一个“,”,非常感谢它就像一个魅力!
    猜你喜欢
    • 1970-01-01
    • 2020-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-05
    • 1970-01-01
    • 2019-07-29
    • 2013-10-08
    相关资源
    最近更新 更多