代码之家  ›  专栏  ›  技术社区  ›  Traveling Tech Guy

如何在将JSON导入Neo4J时避免重复节点

  •  1
  • Traveling Tech Guy  · 技术社区  · 8 年前

    假设我有一个包含人与人之间关系的JSON:

    {
        [
            {
                "name": "mike",
                "loves": ["karen", "david", "joy"],
                "loved": ["karen", "joy"]
            },
            {
                "name": "karen",
                "loves": ["mike", "david", "joy"],
                "loved": ["mike"]
            },
            {
                "name": "joy",
                "loves": ["karen"],
                "loved": ["karen", "david"]
            }
        ]
    }
    

    我想将节点和关系导入Neo4J数据库。对于这个示例,只有一个关系(“LOVES”),每个用户只有两个列表来控制箭头的方向。我使用以下查询导入JSON:

    UNWIND {json} as person
    CREATE (p:Person {name: person.username})
    FOREACH (l in person.loves | MERGE (v:Person {name: l}) CREATE (p)-[:LOVES]->(v))
    FOREACH (f in person.loved | MERGE (v:Person {name: f}) CREATE (v)-[:LOVES]->(p))
    

    我的问题是,我现在有重复的节点(即2个节点 {name: 'karen'} )。我知道我可能需要 UNIQUE 如果每次插入一条记录。但是,在导入大型JSON时,我应该在这里使用什么?(需要明确的是:name属性在JSON中总是唯一的,即没有2个“mike”)。

    1 回复  |  直到 8 年前
        1
  •  3
  •   cybersam    8 年前

    [已编辑]

    因为你不能假设 Person 节点尚不存在,您需要 MERGE 你的 人 节点无处不在。

    如果没有必要使用 loved 数据(即,如果 loves 数据足以创建所有必要的关系):

    UNWIND {json} as person
    MERGE (p:Person {name: person.name})
    FOREACH (l in person.loves | MERGE (v:Person {name: l}) CREATE (p)-[:LOVES]->(v))
    

    另一方面,如果 爱过的 需要数据,然后您需要使用 合并 在创建关系时(因为可能已经存在任何关系)。

    UNWIND {json} as person
    MERGE (p:Person {name: person.name})
    FOREACH (l in person.loves | MERGE (v:Person {name: l}) MERGE (p)-[:LOVES]->(v))
    FOREACH (f in person.loved | MERGE (v:Person {name: f}) MERGE (v)-[:LOVES]->(p))
    

    在这两种情况下,都应该在 :Person(name) 加快查询速度。