繁体   English   中英

如何确保两个节点之间的路径贯穿中间节点的所有连接?

[英]How do I make sure a path between two nodes runs through all the connections of an intermediate node?

我可能正在尝试以最愚蠢的方式解决问题,所以如果有更简单的方法来解决这个问题,请纠正我。 我正在尝试通过图表对一些条件进行建模。 在这种情况下,我们有人员和健康计划。

假设要获得健康计划 A 的资格,您必须在某个地方全职居住,或者您可以在另一个地方全职或兼职居住。

我对此进行建模的方式是使用人员和计划之间的一系列路径,计划之前的最后一个节点是“条件”节点。 我认为这种结构允许 AND 和 OR 关系。 链接到计划的多个条件代表 OR(您可以处于一种状态,也可以处于不同的状态并且是全职)。

这是一个人(黄色节点:“FTai”不要问名字)和计划(绿色节点)之间的路径图片。 在此处输入图片说明

红色节点代表条件,并且规则是,如果存在通过条件的所有传入连接从人到条件的所有路径,则此人可以利用此健康计划。 我如何编写一个查询,为特定的人收集他们可以访问的所有计划?

例如,对于另一个人(“Hai”),查询不应该生成计划,因为他们没有连接到 Full Time 节点,后者馈入 Connection。

有趣的问题。

前提是存在的关系都对条件的评估有意义(例如,没有 :ONCE_LIVED_IN 与夏威夷的关系或可能导致条件错误地评估为真的类似关系),并且提供从一个人到一个计划的关系方向是单向,没有其他传出关系可能会使路径脱轨到不相关的子图,形成您的查询应该相当直接。

这是您描述中图形的创建查询:

create (p:Person{name:'FTai'}), (p2:Person{name:'Hai'})
create (hi:State{name:'Hawaii'})
create (con:Condition)
create (hhc:Plan{name:'Hawaii Healthcare'})
create (ft:EmploymentStatus{name:'Full Time'})
create (pt:EmploymentStatus{name:'Part Time'})
create (con)-[:ALLOWS]->(hhc)
create (ft)-[:REQUIRED_BY]->(con)
create (hi)-[:REQUIRED_BY]->(con)
create (p)-[:HAS_STATUS]->(ft)
create (p)-[:LIVES_IN]->(hi)
create (p2)-[:HAS_STATUS]->(pt)
create (p2)-[:LIVES_IN]->(hi)

这是一个从 :Person 开始并遵循传出关系直到到达 :Condition 的查询。 从那里,对于每个 :Condition 匹配,我们收集从这些路径到 :Condition 的不同最后关系(应该是 :REQUIRED_BY 关系),并将其与传入 :REQUIRED_BY 关系到 :Condition 的数量进行比较。 如果关系的数量相同,那么我们已经将每个 :REQUIRED_BY 关系都满足到 :Condition 中,并且可以返回连接的 :Plan。

MATCH (p:Person{name:'FTai'})-[r*..5]->(con:Condition)
WITH con, COLLECT(DISTINCT LAST(r)) as metRequirements
WHERE SIZE(metRequirements) = SIZE(()-[:REQUIRED_BY]->(con))
MATCH (con)-[:ALLOWS]->(plan:Plan)
RETURN DISTINCT plan

编辑

我的创建查询不包括状态和就业状态之间的 :DEFINED_AS 关系,这些关系的存在会导致我提供的查询不正确匹配(因此 Hai 将错误地满足条件)。

有几种方法可以绕过这种障碍。 您可以进行白名单或黑名单。 对于白名单,您需要提供每个有效关系以在可变长度关系中遍历。

如果存在永远不应为您的查询遍历的关系类型,黑名单可能会更容易。 这是查询的更新版本,即使 :DEFINED_AS 关系到位也能工作:

// you can add to the blacklist as needed, and change to a parameter
WITH ['DEFINED_AS'] as blacklist
MATCH (p:Person{name:'Hai'})-[r*..5]->(con:Condition)
WHERE NONE(rel in r WHERE TYPE(rel) in blacklist)
WITH con, COLLECT(DISTINCT LAST(r)) as metRequirements
WHERE SIZE(metRequirements) = SIZE(()-[:REQUIRED_BY]->(con))
MATCH (con)-[:ALLOWS]->(plan:Plan)
RETURN DISTINCT plan

也许我没有看到您查询的复杂性,但是这样的事情如何:

match (state:State)-[:REQUIRED_BY]->(and:Condition)<-[:REQUIRED_BY]-(status:EmploymentStatus)
with state,status,and
match (status)<-[:HAS_STATUS]-(person:Person)-[:LIVES_IN]->(state)
with person, and
match (and)-[:ALLOWS]->(plan:Plan)
return person, plan 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM