【问题标题】:Building a relationship in Neo4j using Neo4j Spark Connector使用 Neo4j Spark 连接器在 Neo4j 中建立关系
【发布时间】:2022-10-19 02:44:34
【问题描述】:

我正在尝试使用 Spark-Neo4j 连接器在 Neo4j 中建立一个简单的关系。我的数据框如下所示:

df_new= spark.createDataFrame(
    [("CompanyA",'A','CompanyA','B'),("CompanyB",'B','CompanyB','C') ],
    ["name",'gid','description','parent_gid']
)

所需的树应如下所示:

我写的查询是这样的:

query = """
MERGE (c:Company {gid:event.gid})
ON CREATE SET c.name=event.name, c.description=event.description 
ON MATCH SET c.name=event.name, c.description=event.description
MERGE (p:Company {gid:event.parent_gid}) 
MERGE (p)-[:PARENT_OF]->(c)
"""

df_new.write\
    .mode("Overwrite")\
    .format("org.neo4j.spark.DataSource")\
    .option("url", "bolt://localhost:7687")\
    .option("authentication.type", "basic")\
    .option("authentication.basic.username", username)\
    .option("authentication.basic.password", password)\
    .option("query", query)\
    .save()

但是我的代码最终创建了节点而不是合并它,我最终得到了 B 公司的两个节点

【问题讨论】:

    标签: pyspark neo4j


    【解决方案1】:

    你有完全正确的逻辑,只是有一些细微的差别在起作用,很难确定。这篇文章有你的答案;阅读最后关于唯一约束的部分:https://neo4j.com/developer/kb/understanding-how-merge-works/

    一种解决方案是将您的查询更改为:

    query = '''
      merge (c:Company {gid:event.gid})
      set c.name = event.name, c.description = event.description
      merge (p:Company {gid:event.parent_gid})
      set p.name = event.name, p.description = event.description
      merge (p)-[:PARENT_OF]->(c)
    '''
    

    现在在执行并发操作时,cypher 有足够的唯一约束来避免重复 gid = "B"

    【讨论】: