我正在模拟通过逻辑门的输入。 我想要获得活动路径。我目前的方法是为每个活动逻辑门创建一个链接,说明它在哪个SIM中打开。但这并不是那么简洁。 另外,还有递归的问题,可能还有更多层次。 并且,当 Out1 和 Out2 处于活动状态时,仅报告 Out2。
有没有办法递归这种类型的逻辑?
样本数据
CREATE
(s1:Sim {id:1}),(s2:Sim{id:2}),(s3:Sim{id:3}),(s4:Sim{id:4}),
(e1:Inputt {name: 'In1'}),(e2:Inputt {name: 'In2'}),(e3:Inputt{name: 'In3'}),(e4:Inputt{name: 'In4'}),(e5:Inputt{name: 'In5'}),(e6:Inputt{name: 'In6'}),
(x1:Outputt {name: 'Out1'}),(x2:Outputt {name: 'Out2'}),
(a1:GateAND),(a2:GateAND),(a3:GateAND),
(o1:GateOR),(o2:GateOR),
(e1)<-[:ACTIVE]-(s1),
(e3)<-[:ACTIVE]-(s1),
(e2)<-[:ACTIVE]-(s2),
(e4)<-[:ACTIVE]-(s2),
(e4)<-[:ACTIVE]-(s3),
(e5)<-[:ACTIVE]-(s3),
(e4)<-[:ACTIVE]-(s4),
(e5)<-[:ACTIVE]-(s4),
(e6)<-[:ACTIVE]-(s4),
(e1)-[:INTO]->(o1),
(e2)-[:INTO]->(o1),
(o1)-[:INTO]->(a1),
(e3)-[:INTO]->(a1),
(e4)-[:INTO]->(a2),
(e5)-[:INTO]->(a2),
(a1)-[:INTO]->(o2),
(a2)-[:INTO]->(o2),
(o2)-[:INTO]->(a3),
(e6)-[:INTO]->(a3),
(o2)-[:OUT]->(x1),
(a3)-[:OUT]->(x2)
添加:
// First level OR gates only need one active input
MATCH (sim:Sim)-[:ACTIVE]->(inp:Inputt)-[:INTO]->(rule:GateOR)
WITH sim, rule, COUNT(inp) AS sfrEventCount
WHERE sfrEventCount >=1
MERGE (sim)-[:ACTIVE]->(rule)
// Add active to and gates
MATCH (inp:Inputt|GateOR)-[:INTO]->(gate:GateAND)
WITH ELEMENTID(gate) as gateId, COUNT(inp) AS inpCount
WITH apoc.map.fromPairs(COLLECT([gateId, inpCount])) AS gateIdCountMap
MATCH (sim:Sim)-[:ACTIVE]->(inp2:Inputt|GateOR)-[:INTO]->(rule)
WITH sim, rule, gateIdCountMap, COUNT(inp2) AS sinpCount
WHERE gateIdCountMap[ELEMENTID(rule)] = sinpCount
MERGE (sim) -[:ACTIVE]->(rule)
// Next level OR
MATCH (sim:Sim)-[:ACTIVE]->(inp:GateOR|GateAND)-[:INTO]->(rule:GateOR)
WITH sim, rule, COUNT(inp) AS sfrEventCount
WHERE sfrEventCount >=1
MERGE (sim)-[:ACTIVE]->(rule)
// DO the and again
// Outputs
MATCH (s:Sim)-[:ACTIVE]->(gate:GateAND|GateOR)-[:OUT]->(x:Outputt), (g2:GateAND|GateOR)<--(s2:Sim)
WHERE NOT EXISTS ((gate)-->(g2))
MERGE (s)-[:ACTIVE]->(x)
感兴趣的结果。我希望 Out1 在 Sim 1 中处于活动状态,但在某个地方 Sim 4 优先。
MATCH (s:Sim)-->(x:Outputt) return s, x
此查询将找到合法路径:
MATCH path = (sim:Sim)-[:ACTIVE]->(input:Inputt)-[:INTO|OUT*0..]->(output:Outputt)
WHERE ALL(node IN nodes(path)[2..-1]
WHERE
(node:GateAND AND ALL(incoming IN [(other)-[:INTO]->(node) | other] WHERE (sim)-[:ACTIVE|INTO*]->(incoming)))
OR
node:GateOR
)
RETURN sim, output, COLLECT(path) AS paths
但请注意,如果您有大量相关数据或较长路径,查询将会很慢甚至耗尽内存。如果可以接受,您可以通过对可变长度路径模式施加合理的上限来改善其中的一些问题。例如:
MATCH path = (sim:Sim)-[:ACTIVE]->(input:Inputt)-[:INTO|OUT*0..8]->(output:Outputt)
WHERE ALL(node IN nodes(path)[2..-1]
WHERE
(node:GateAND AND ALL(incoming IN [(other)-[:INTO]->(node) | other] WHERE (sim)-[:ACTIVE|INTO*..9]->(incoming)))
OR
node:GateOR
)
RETURN sim, output, COLLECT(path) AS paths
根据您的示例数据,这是输出:
╒══════════════╤═════════════════════════╤══════════════════════════════════════════════════════════════════════╕
│sim │output │paths │
╞══════════════╪═════════════════════════╪══════════════════════════════════════════════════════════════════════╡
│(:Sim {id: 1})│(:Outputt {name: "Out1"})│[(:Sim {id: 1})-[:ACTIVE]->(:Inputt {name: "In3"})-[:INTO]->(:GateAND)│
│ │ │-[:INTO]->(:GateOR)-[:OUT]->(:Outputt {name: "Out1"}), (:Sim {id: 1})-│
│ │ │[:ACTIVE]->(:Inputt {name: "In1"})-[:INTO]->(:GateOR)-[:INTO]->(:GateA│
│ │ │ND)-[:INTO]->(:GateOR)-[:OUT]->(:Outputt {name: "Out1"})] │
├──────────────┼─────────────────────────┼──────────────────────────────────────────────────────────────────────┤
│(:Sim {id: 3})│(:Outputt {name: "Out1"})│[(:Sim {id: 3})-[:ACTIVE]->(:Inputt {name: "In4"})-[:INTO]->(:GateAND)│
│ │ │-[:INTO]->(:GateOR)-[:OUT]->(:Outputt {name: "Out1"}), (:Sim {id: 3})-│
│ │ │[:ACTIVE]->(:Inputt {name: "In5"})-[:INTO]->(:GateAND)-[:INTO]->(:Gate│
│ │ │OR)-[:OUT]->(:Outputt {name: "Out1"})] │
├──────────────┼─────────────────────────┼──────────────────────────────────────────────────────────────────────┤
│(:Sim {id: 4})│(:Outputt {name: "Out1"})│[(:Sim {id: 4})-[:ACTIVE]->(:Inputt {name: "In4"})-[:INTO]->(:GateAND)│
│ │ │-[:INTO]->(:GateOR)-[:OUT]->(:Outputt {name: "Out1"}), (:Sim {id: 4})-│
│ │ │[:ACTIVE]->(:Inputt {name: "In5"})-[:INTO]->(:GateAND)-[:INTO]->(:Gate│
│ │ │OR)-[:OUT]->(:Outputt {name: "Out1"})] │
├──────────────┼─────────────────────────┼──────────────────────────────────────────────────────────────────────┤
│(:Sim {id: 4})│(:Outputt {name: "Out2"})│[(:Sim {id: 4})-[:ACTIVE]->(:Inputt {name: "In6"})-[:INTO]->(:GateAND)│
│ │ │-[:OUT]->(:Outputt {name: "Out2"}), (:Sim {id: 4})-[:ACTIVE]->(:Inputt│
│ │ │ {name: "In4"})-[:INTO]->(:GateAND)-[:INTO]->(:GateOR)-[:INTO]->(:Gate│
│ │ │AND)-[:OUT]->(:Outputt {name: "Out2"}), (:Sim {id: 4})-[:ACTIVE]->(:In│
│ │ │putt {name: "In5"})-[:INTO]->(:GateAND)-[:INTO]->(:GateOR)-[:INTO]->(:│
│ │ │GateAND)-[:OUT]->(:Outputt {name: "Out2"})] │
└──────────────┴─────────────────────────┴──────────────────────────────────────────────────────────────────────┘