Neo4j:查询具有指定关系的所有路径

时间:2014-01-03 15:09:59

标签: neo4j cypher

我正在尝试查询图形以返回具有指定关系的所有路径。

我正在构建一个家谱,我有以下节点:

  1. 边缘
  2. 连接两个人的关系是:

    1. PARENT
    2. COUPLE
    3. 所以一些数据的例子是:

      1. 一个:人< - [:CHILD] - (边缘) - [:PARENT] - GT; B:人
      2. 一个:人< - [:COUPLE] - (R 2:边缘) - [:COUPLE] - 以及c:人< - [:PARENT] - (R3:边缘) - [:CHILD] - GT; d :人
      3. 在我的查询中,我希望能够在前端绘制图形,因此我需要获得每个人员和边缘节点以及它们之间的每个关系,这些关系与我的初始人员相关联。

        我最初尝试使用allShortestPaths来减少节点的重复,但这会错过很多关系(例如,如果父母有多个孩子,那么只返回与孩子的母亲或父亲的关系,而不是两者都有)。我当前的密码如下(我通过过滤仅存在于Relationships上的type属性来区分Edge和Person节点):

        START person = node({personId})
        MATCH person-[:PARENT | CHILD | COUPLE*]-(relatedPeople:Person)
        WITH relatedPeople, person
        MATCH p = allShortestPaths(person-[:PARENT|CHILD|COUPLE]-(relatedPeople))
        WITH [n in nodes(p) WHERE not(has(n.type))] AS people, last([n in nodes(p) WHERE has(n.type) | id(n)]) AS relationship, [r in rels(p) | TYPE(r)] AS rels
        WITH relationship, rels, last(people) AS destination, [p in people | id(p)] AS source
        MATCH destination-[:NAME]->(name), destination-[:GENDER]->gender
        RETURN source, id(destination), relationship, rels, collect(name), gender
        

        我认为这是有效的,但意识到最短路径会降低一些关系。我只想找到所有相关节点和所有关系,然后处理结果以构建正确的格式,但我觉得可能有一种更容易/更有效的方法。

        更新06/01/2014

        我已经尝试返回所有路径,但模型可以有循环,因此返回的路径数随着大小呈指数增长。下面的密码创建一个样本数据集。

        CREATE (p1:Person)<-[:CHILD]-(r1:Edge { type:'parentChild' })-[:PARENT]->(p2:Person)
        <-[:COUPLE]-(r2:Edge { type:'couple' })-[:COUPLE]->(p3:Person)<-[:PARENT]-
        (r3:Edge { type:'parentChild' })-[:CHILD]->p1<-[:COUPLE]-(r4:Edge { type:'couple' })-[:COUPLE]->
        (p4:Person)<-[:CHILD]-(r5:Edge { type:'parentChild' })-[:PARENT]->(p5:Person)<-[:COUPLE]-
        (r6:Edge { type:'couple' })-[:COUPLE]->(p6:Person)<-[:PARENT]-(r7:Edge { type:'parentChild' })-
        [:CHILD]->p4, 
        p5<-[:PARENT]-(r8:Edge { type:'parentChild' })-[:CHILD]->(p7:Person),
        p5<-[:PARENT]-(r9:Edge { type:'parentChild' })-[:CHILD]->(p8:Person), 
        p5<-[:PARENT]-(r10:Edge { type:'parentChild' })-[:CHILD]->(p9:Person)
        

        图像显示数据视图。 Sample Data

        所需的结果是每个Node-Edge-Node连接的一行。这个数据共有10个,但是当我返回所有路径时,由于循环,我得到128行。是否有更有效的过滤路径的方法?

1 个答案:

答案 0 :(得分:0)

为了解决这个问题,我使用了以下密码。

START person = node({personId})' +
MATCH person-[:PARENT | CHILD | COUPLE*0..]-(p:Person)
WITH distinct p
MATCH p-[r]-(edge:Edge), p-[:NAME]->(name), p-[:GENDER]->gender, edge-[:FACT]->(fact)
RETURN p, id(p), collect(name), gender, type(r), id(edge), collect(fact.type)
ORDER BY id(edge)

我曾经在关系中使用 * 0 .. 来匹配所有连接的“Person”节点,包括原始节点。删除重复项后,只需查找节点之间的所有关系以及每个点上的额外信息。

这个cypher为每个“人”到“边缘”关系返回了一行。 “人”信息中有一些重复,但是一旦返回数据就很容易解析出来。

感谢您的评论和帮助。