【问题标题】:All valid paths through graph with Cypher使用 Cypher 通过图的所有有效路径
【发布时间】:2018-12-17 12:30:13
【问题描述】:

我正在尝试编写一个我怀疑很简单但无法找出正确方法的查询。我在 Neo4J 图形模型中有组织结构数据。它由 org_unit 节点(团队)和 BELONGS_TO 关系组成。每个关系都有一个开始和结束日期来定义该关系的有效期。我想通过图表返回所有基于日期有效的路径。路径可以有不同的长度

这似乎需要过滤关系,因此“较高”关系适合“较低”关系的有效期(我是自下而上)以下有助于实现结果:

MATCH (a:Org_unit)-[r1:BELONGS_TO]->(b:Org_unit)
MATCH (c:Org_unit)-[r2:BELONGS_TO]->(d:Org_unit)
WHERE r1.endda_epoch > r2.begda_epoch 
AND r1.begda_epoch <= r2.endda_epoch 
AND b=c
RETURN a,b,c,d

但是,我真的很想返回所有完整的路径。我认为我可能能够使用 apoc.path.expand 函数之一,但我认为我需要根据属性过滤关系 - 我不知道该怎么做

谢谢

亚当

【问题讨论】:

    标签: neo4j cypher neo4j-apoc


    【解决方案1】:

    示例数据

    为了方便可能的进一步答案和解决方案,我记下了我的图表创建声明:

    CREATE
      (a:OrgUnit {name: 'A'})
        <-[:BELONGS_TO {beginDate: date('2019-01-01'), endDate: date('2019-12-31')}]-(b1:OrgUnit {name: 'B1'}),
      (a)<-[:BELONGS_TO {beginDate: date('2000-01-01'), endDate: date('2019-12-31')}]-(b2:OrgUnit {name: 'B2'}),
      (a)<-[:BELONGS_TO {beginDate: date('2010-01-01'), endDate: date('2019-12-31')}]-(b3:OrgUnit {name: 'B3'}),
      (b2)<-[:BELONGS_TO {beginDate: date('2010-01-01'), endDate: date('2019-12-31')}]-(c1:OrgUnit {name: 'C1'}),
      (b2)<-[:BELONGS_TO {beginDate: date('2015-01-01'), endDate: date('2019-12-31')}]-(c2:OrgUnit {name: 'C2'}),
      (b2)<-[:BELONGS_TO {beginDate: date('2018-01-01'), endDate: date('2019-12-31')}]-(c3:OrgUnit {name: 'C3'}),
      (b3)<-[:BELONGS_TO {beginDate: date('2010-01-01'), endDate: date('2019-12-31')}]-(c4:OrgUnit {name: 'C4'}),
      (b3)<-[:BELONGS_TO {beginDate: date('2020-01-01'), endDate: date('2021-12-31')}]-(c5:OrgUnit {name: 'C5'}),
      (c4)<-[:BELONGS_TO {beginDate: date('2019-01-01'), endDate: date('2019-12-31')}]-(d1:OrgUnit {name: 'D1'});
    

    解决方案

    MATCH path = (root:OrgUnit {name: 'A'})<-[*..10]-(:OrgUnit)
    WITH path WHERE 
      ALL(x IN relationships(path) WHERE x.beginDate <= $startDate) AND
      ALL(x IN relationships(path) WHERE x.endDate >= $endDate)
    RETURN path;
    

    使用的参数:

    • $startDate = date('2018-01-01')
    • $endDate = date('2019-01-01')

    说明:

    • 第1行:匹配从根OrgUnit(CEO)到每个OrgUnit的所有可能路径,假设最大组织深度为10
    • 第 3 行:过滤掉那些并非所有关系都符合我们的$startDate 参数的路径
    • 第 4 行:过滤掉那些并非所有关系都符合我们的$endDate 参数的路径
    • 第 5 行:渲染结果路径

    结果

    OrgUnits B1、C5 和 D1 被省略,因为它们仅在“2019-01-01”、“2020-01-01”和“2019-01-01”期间有效。

    备注

    Neo4j 不专注于搜索和过滤关系属性。将这些属性建模为节点或节点的属性会显着提高性能,尤其是对于大型图。

    【讨论】:

    • 这太好了 - 谢谢。有没有一种方法可以根据从 C1 到 B2 的关系的开始和结束日期过滤例如从 A2 到 B2 的关系,并将其扩展到完整的图表 - 以便每个“上层”关系有效期都与那些“降低”?这可能会导致多个可能的路径通过 - 我最终想要做的是将生成的路径转换为包含级别列的表 - 每个有效路径一行,并包括有效期的“总体”开始和结束日期那条路。希望这是有道理的:)
    • 您能否指定一个包含您期望的具体值的结果表?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-02
    • 2017-12-19
    • 1970-01-01
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多