1

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

+------------+-------------+------------+-------------+
|     ID     |      Name   |  FatherID  |  MotherID   |
+------------+-------------+------------+-------------+
| 1          | Mom Doe     |            |             |
| 2          | Dad Doe     |            |             |
| 3          | Big Sis     |  2         |  1          |
| 4          | Lil Bro     |  2         |  1          |
+------------+-------------+------------+-------------+

我正在尝试制作一个家谱,如下所示:

在此处输入图像描述

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

这是我尝试过的,但没有奏效:

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。

我的一个想法是让任何拥有 NULLFatherID并且MotherID有亲属关系的人成为 SPOUSE,但如果家谱有祖父母,那就行不通了。

一个解决方案似乎真的很棘手——也许首先创建所有节点并创建SIBLING关系。然后遍历 csv 并产生CHILD关系?

有什么方法可以让我通常吞下一个 csv 并创建这个简单的图表?

感谢您阅读本文。

4

2 回答 2

1

根据您的数据集,这远非有效,这需要大量调整,但对于这个基本数据集,它正在工作:

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);

效率问题将来自 MATCH 部分中的笛卡尔积。

我还添加了一个技巧,我用零填充了空的父亲和母亲 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);
于 2016-05-04T06:07:50.620 回答
1

这种SIBLING关系是不需要的,因为您可以通过匹配共享父母的人来确定兄弟关系。

这是一种可能满足您需求的方法。

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

步骤 1:生成所有Person节点

LOAD CSV WITH HEADERS FROM 'file:///Users/.../import_for_Neo4j.csv' AS line
MERGE (p:Person {id: line.ID, name: line.Name});

请注意,我使用MERGE而不是CREATE, 以避免创建重复项。

第 2 步:生成所有关系(父亲、母亲、配偶)

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))

以下是您的示例数据的结果:

结果图

寻找兄弟姐妹

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

MATCH (child:Person {name:'Lil Bro'})-[:MOTHER|FATHER]->()<-[:MOTHER|FATHER]-(sibling)
RETURN child, COLLECT(DISTINCT sibling)
于 2016-05-05T17:02:44.707 回答