在neo4j中读取csv时,根据ID创建和推断关系

在neo4j中读取csv时,根据ID创建和推断关系,csv,neo4j,cypher,family-tree,Csv,Neo4j,Cypher,Family Tree,我有一个简单的csv,有4行,如下所示: +------------+-------------+------------+-------------+ | ID | Name | FatherID | MotherID | +------------+-------------+------------+-------------+ | 1 | Mom Doe | | | | 2

我有一个简单的csv,有4行,如下所示:

+------------+-------------+------------+-------------+
|     ID     |      Name   |  FatherID  |  MotherID   |
+------------+-------------+------------+-------------+
| 1          | Mom Doe     |            |             |
| 2          | Dad Doe     |            |             |
| 3          | Big Sis     |  2         |  1          |
| 4          | Lil Bro     |  2         |  1          |
+------------+-------------+------------+-------------+
我正在制作一个家谱,它看起来像这样:

这里的诀窍是,我必须仅基于两件事来创建这些关系:
FatherID
MotherID
。这是可行的。但它需要以某种有条件的方式应用关系

以下是我尝试过的,但没有成功:

LOAD CSV WITH HEADERS FROM
'file:///Users/.../import_for_Neo4j.csv' AS line
WITH line
CREATE (person:Person {id:line.ID})
SET person.Name=line.Name,
    person.MotherID=line.MotherID,
    person.FatherID=line.FatherID
WITH person
CREATE (a:Person {Name:'Mom Doe'})-[:SPOUSE]->(b:Person {Name:'Dad Doe'})
RETURN a 
但后来我意识到,即使这真的有效,那又有什么意义呢?我必须手动输入每个家庭成员的姓名,这将否定首先加载csv的全部意义。如果是这样的话,我也可以直接在Sublime中手工输入所有内容,而不去读csv

我的一个想法是,任何一个父亲ID和母亲ID为空的人都可以成为配偶,但如果家谱上有祖父母,那就行不通了

一个解决方案似乎非常棘手——可能首先创建所有节点并创建
同级关系。然后在csv上迭代并生成
子关系

有没有什么方法可以让我把一个csv做成一个简单的图表


谢谢你阅读这篇文章

根据您的数据集,这远远不够有效。这需要进行大量调整,但对于这个基本数据集,它可以正常工作:

LOAD CSV WITH HEADERS FROM
'file:///test.csv' AS line
WITH line
CREATE (p:Person {id: line.id})
SET p.name = line.name, p.motherId = line.motherId, p.fatherId = line.fatherId
WITH p
MATCH (p1:Person), (p2:Person)
WHERE p.fatherId = p1.id AND p.motherId = p2.id
MERGE (p1)-[:SPOUSE]->(p2);
效率问题将来自匹配部分的笛卡尔积

我还增加了一个技巧,我用零填充了空的父亲和母亲ID

已更新

与子女的父母关系:

LOAD CSV WITH HEADERS FROM
'file:///test.csv' AS line
WITH line
CREATE (p:Person {id: line.id})
SET p.name = line.name, p.motherId = line.motherId, p.fatherId = line.fatherId
WITH p
MATCH (p1:Person), (p2:Person)
WHERE p.fatherId = p1.id AND p.motherId = p2.id
MERGE (p1)-[:SPOUSE]->(p2)
WITH p
MATCH (father:Person)
WHERE p.fatherId = father.id
MERGE (p)-[:PARENT {type: 'FATHER'}]->(father)
WITH p
MATCH (mother:Person)
WHERE p.motherId = mother.id
MERGE (p)-[:PARENT {type: 'MOTHER'}]->(mother);

不需要兄弟姐妹关系,因为您可以通过匹配共享父母的人来确定兄弟姐妹关系

这里有一种方法可能适合您的需要

注意:我选择使用父关系而不是子关系来保留CSV文件中的语义信息。如果您愿意,您可以简化我的答案,只需使用
CHILD

步骤1:生成所有
Person
节点 请注意,我使用了
MERGE
而不是
CREATE
,以避免创建重复项

步骤2:生成所有关系(父亲、母亲、配偶) 以下是使用示例数据得出的结果:

寻找兄弟姐妹 以下是您如何找到“Lil Bro”的所有兄弟姐妹:


MATCH(child:Person{name:'Lil Bro})-[:MOTHER | FATHER]>()这是一个非常好的开始,感谢您编写了此代码。你知道我们如何表示孩子们也和父母有关系吗?
LOAD CSV WITH HEADERS FROM 'file:///Users/.../import_for_Neo4j.csv' AS line
MERGE (p:Person {id: line.ID, name: line.Name});
LOAD CSV WITH HEADERS FROM 'file:///Users/.../import_for_Neo4j.csv' AS line
MATCH (p:Person {id: line.ID})
WITH p, line
OPTIONAL MATCH (m:Person {id: line.MotherID})
FOREACH (x IN CASE WHEN m IS NULL THEN [] ELSE [1] END | MERGE (p)-[:MOTHER]->(m))
WITH p, m, line
OPTIONAL MATCH (f:Person {id: line.FatherID})
WITH p, m, f
FOREACH (x IN CASE WHEN f IS NULL THEN [] ELSE [1] END | MERGE (p)-[:FATHER]->(f))
FOREACH (y IN CASE WHEN m IS NULL OR f IS NULL THEN [] ELSE [1] END | MERGE (m)-[:SPOUSE]->(f))
MATCH (child:Person {name:'Lil Bro'})-[:MOTHER|FATHER]->()<-[:MOTHER|FATHER]-(sibling)
RETURN child, COLLECT(DISTINCT sibling)