首页 文章

使用Neo4J创建族树

提问于
浏览
6

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

{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 回答

  • 1

    你可能也看看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);
    
  • 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有索引!

  • 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;此通用解决方案适用于任何数据视图,因此可扩展 . 我现在正在努力添加其他数据,例如位置(纬度/经度),文档(特别是链接人员,例如人口普查)等 .

  • 5

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

    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"]
    

相关问题