使用Neo4J创建族树

时间:2015-01-07 20:01:16

标签: json neo4j

我在Neo4J中有一组家谱的数据,我正在尝试构建一个生成类似于以下内容的JSON数据集的Cypher查询:

{Name:  "Bob",
      parents: [
          {Name:  "Roger",
             parents: [
                Name: "Robert",
                Name: "Jessica"
             ]},
          {Name:  "Susan",
             parents: [
                Name: "George",
                Name: "Susan"
             ]}
      ]}

我的图表在MEMBER节点之间具有PARENT关系(即MATCH(p.Member) - [:PARENT] - >(c.Member))。我发现Nested has_many relationships in cypherneo4j cypher nested collect最终将所有父母一起分组到我正在搜索的主要子节点。

根据反馈添加一些清晰度:

每个成员都有唯一的标识符。工会目前都与父母关系有关。所有内容都被编入索引,以便性能不会受到影响。当我运行查询以返回节点图时,我得到了我期望的结果。我正在尝试返回一个可用于D3的可视化目的输出。理想情况下,这将通过Cypher查询完成,因为我正在使用API​​从正在构建的前端访问neo4j。

添加示例查询:

MATCH (p:Person)-[:PARENT*1..5]->(c:Person)
WHERE c.FirstName = 'Bob'
RETURN p.FirstName, c.FirstName

此查询返回五代的每个父级列表,但不是显示层次结构,而是将“Bob”列为每个关系的子级。是否有Cypher查询至少会显示数据中的每个关系?我可以根据需要对其进行格式化...

4 个答案:

答案 0 :(得分:6)

您可能还要查看Rik van Bruggens Blog on his family data

关于您的查询

您已在此处创建路径模式:(p:Person)-[:PARENT*1..5]->(c:Person)您可以将其分配给变量tree,然后对该变量进行操作,例如返回树,或nodes(tree)rels(tree)或以其他方式对该集合进行操作:

MATCH tree = (p:Person)-[:PARENT*1..5]->(c:Person)
WHERE c.FirstName = 'Bob'
RETURN nodes(tree), rels(tree), tree, length(tree),
       [n in nodes(tree) | n.FirstName] as names

另请参阅密码参考卡:http://neo4j.com/docs/stable/cypher-refcard和在线培训http://neo4j.com/online-training以了解有关Cypher的更多信息。

别忘了

create index on :Person(FirstName);

答案 1 :(得分:3)

我建议构建一种方法将数据压缩成数组。如果他们的对象没有UUID,你可能希望在展平时给他们ID,然后为每条记录都有一个parent_id键。

然后,您可以将其作为一组cypher查询(对查询REST API发出多个请求,或使用批处理REST API)运行,或者将数据转储到CSV并使用cypher的LOAD CSV命令加载对象。

使用params的示例cypher命令将是:

CREATE (:Member {uuid: {uuid}, name: {name}}

然后使用父ID和子ID再次遍历列表:

MATCH (m1:Member {uuid: {uuid1}}), (m2:Member {uuid: {uuid2}})
CREATE m1<-[:PARENT]-m2

确保成员的ID有索引!

答案 2 :(得分:3)

系谱数据可能符合GEDCOM标准,包括两种类型的节点:人员和联盟。 Person节点具有其标识符和通常的人口统计事实。 Union节点有一个union_id和关于union的事实。在GEDCOM,Family是将这两者结合在一起的第三个元素。但是在Neo4j中,我发现它也适合在Person节点中包含union_id。我使用了5种关系:父亲,母亲,丈夫,妻子和孩子。这个家庭是两个父母,有一个向内的向量,每个孩子都有向外的向量。图像说明了这一点。这对于可视化连接和生成假设非常方便。例如,考虑附图和我的祖先爱德华G坎贝尔,1917年工会的产物,其中三兄弟娶了来自8944工会的三个Vaught姐妹和两个与2945工会结合的Gaither姐妹。另外,在左上角,Mahala Campbell如何与她结婚继哥哥约翰格里尔阿姆斯特朗。马哈拉旁边是伊丽莎白·坎贝尔,她与其他坎贝尔结婚,但可能与他们直接相关。同样地,你可以在右上角假设Rachael Jacobs,以及她如何与其他Jacobs联系起来。 Notice the query.  From the few initial nodes visualized, you can click to open others. 我使用批量插入,可以在一分钟内填充~30000个Person节点和~100,000个关系。我有一个小的.NET函数,它从数据视图返回JSon;此通用解决方案适用于任何数据视图,因此可扩展。我现在正在努力添加其他数据,例如位置(纬度/经度),文档(特别是链接人员,例如人口普查)等。

答案 3 :(得分:2)

到目前为止我找到的唯一方法是获取我正在寻找的数据实际上是返回关系信息,如下所示:

MATCH ft = (person {firstName: 'Bob'})<-[:PARENT]-(p:Person)
RETURN EXTRACT(n in nodes(ft) | {firstName: n.firstName}) as parentage
ORDER BY length(ft);

这将返回一个我可以变形的数据集:

["Bob", "Roger"]
["Bob", "Susan"]
["Bob", "Roger", "Robert"]
["Bob", "Susan", "George"]
["Bob", "Roger", "Jessica"]
["Bob", "Susan", "Susan"]