[英]How do I make sure a path between two nodes runs through all the connections of an intermediate node?
I may be trying to solve a problem in the stupidest way possible, so please correct me if there's an easier way to do this.我可能正在尝试以最愚蠢的方式解决问题,所以如果有更简单的方法来解决这个问题,请纠正我。 I'm trying to model some conditionals via a graph.我正在尝试通过图表对一些条件进行建模。 In this case, we have people and health plans.在这种情况下,我们有人员和健康计划。
Let's say that to qualify for health plan A, you have to live in a certain place and be full-time, or you can live in another place and be full or part time.假设要获得健康计划 A 的资格,您必须在某个地方全职居住,或者您可以在另一个地方全职或兼职居住。
The way I'm modeling this is with a series of paths between a person and a plan, with the last node before the plan being a "Condition" node.我对此进行建模的方式是使用人员和计划之间的一系列路径,计划之前的最后一个节点是“条件”节点。 I think this structure allows for AND and OR relationships.我认为这种结构允许 AND 和 OR 关系。 More than one Condition linking to a plan represents ORs (You can be in one state OR you can be in a different state AND be full time).链接到计划的多个条件代表 OR(您可以处于一种状态,也可以处于不同的状态并且是全职)。
Here's a picture of a path between one person (yellow node: "FTai" don't ask about the name) and a plan (green node).这是一个人(黄色节点:“FTai”不要问名字)和计划(绿色节点)之间的路径图片。
The red node represents the Condition, and the rule is that this person can utilize this health plan if all there is a path from the person to the Condition through all of the Condition's incoming connections.红色节点代表条件,并且规则是,如果存在通过条件的所有传入连接从人到条件的所有路径,则此人可以利用此健康计划。 How do I write a query that, for a particular person, collects all the plans they can access?我如何编写一个查询,为特定的人收集他们可以访问的所有计划?
For instance, for the other person ("Hai"), the query shouldn't produce the plan because they aren't connected to the Full Time node, which feeds into the Connection.例如,对于另一个人(“Hai”),查询不应该生成计划,因为他们没有连接到 Full Time 节点,后者馈入 Connection。
Interesting question.有趣的问题。
Provided that the relationships present are all meaningful to the evaluation of the condition (for example, no :ONCE_LIVED_IN relationship to Hawaii or similar that might cause the condition to wrongly evaluate to true), and provided the relationship direction from a person to a plan is all one-way, with no other outgoing relationships that might derail a path into an irrelevant subgraph, it should be fairly straight forward to form your query.前提是存在的关系都对条件的评估有意义(例如,没有 :ONCE_LIVED_IN 与夏威夷的关系或可能导致条件错误地评估为真的类似关系),并且提供从一个人到一个计划的关系方向是单向,没有其他传出关系可能会使路径脱轨到不相关的子图,形成您的查询应该相当直接。
Here's a creation query for the graph in your description:这是您描述中图形的创建查询:
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)
Here's a query that starts at a :Person and follows outgoing relationships until it reaches a :Condition.这是一个从 :Person 开始并遵循传出关系直到到达 :Condition 的查询。 From there, for each :Condition matched, we collect the distinct last relationships from those paths into that :Condition (should be :REQUIRED_BY relationships), and compare that to the number of incoming :REQUIRED_BY relationships into the :Condition.从那里,对于每个 :Condition 匹配,我们收集从这些路径到 :Condition 的不同最后关系(应该是 :REQUIRED_BY 关系),并将其与传入 :REQUIRED_BY 关系到 :Condition 的数量进行比较。 If the number of relationships are the same, then we've met every :REQUIRED_BY relationship into the :Condition, and can return the connected :Plan.如果关系的数量相同,那么我们已经将每个 :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
EDIT编辑
My creation query didn't include the :DEFINED_AS relationships between states and employment status, and the presence of those relationships will cause the query I provided to match improperly (so Hai will wrongly fulfill the condition).我的创建查询不包括状态和就业状态之间的 :DEFINED_AS 关系,这些关系的存在会导致我提供的查询不正确匹配(因此 Hai 将错误地满足条件)。
There are a few ways around this kind of obstacle.有几种方法可以绕过这种障碍。 You can do whitelisting or blacklisting.您可以进行白名单或黑名单。 For whitelisting, you'll need to provide every valid relationship to traverse in the variable-length relationship.对于白名单,您需要提供每个有效关系以在可变长度关系中遍历。
Blacklisting will likely be easier, if there are relationship types that should never be traversed for your query.如果存在永远不应为您的查询遍历的关系类型,黑名单可能会更容易。 Here's an updated version of the query that will work even if the :DEFINED_AS relationships are in place:这是查询的更新版本,即使 :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
Maybe I don't see the complexity of your query but how about something like this:也许我没有看到您查询的复杂性,但是这样的事情如何:
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.