I'm looking for help with the syntax to create logic gates.
I want to identify in which sims, which gates are open.
Data created using:
CREATE
(a:Gate {name: 'gate a'}),
(b:Gate {name: 'gate b'}),
(c:Gate {name: 'gate c'}),
(x1:X {name: 'sim 1'}),(x2:X {name: 'sim 2'}), (x3:X {name: 'sim 3'}),
(e1:E {name: 'event 1'}),(e2:E {name: 'event 2'}), (e3:E {name: 'event 3'}),
(e1)-[:AND]->(a),
(e1)-[:AND]->(b),
(e2)-[:AND]->(b),
(e1)-[:AND]->(c),
(e2)-[:AND]->(c),
(e3)-[:AND]->(c),
(x1)-[:HAS]->(e1),
(x2)-[:HAS]->(e1),
(x2)-[:HAS]->(e2),
(x3)-[:HAS]->(e2),
(x3)-[:HAS]->(e1),
(x3)-[:HAS]->(e3)
Assuming that your DB has no duplicate HAS
or AND
relationships (between the same pair of nodes), you can:
For example (this also sorts the results by sim.name
):
MATCH (e)-[:AND]->(g:Gate)
WITH ELEMENTID(g) as gId, COUNT(e) AS gEventCount
WITH apoc.map.fromPairs(COLLECT([gId, gEventCount])) AS gIdCountMap
MATCH (sim:X)-[:HAS]->(event)-[:AND]->(gate)
WITH sim, gate, gIdCountMap, COUNT(event) AS sgEventCount
WHERE gIdCountMap[ELEMENTID(gate)] = sgEventCount
RETURN sim, gate
ORDER BY sim.name
The result of above query is:
╒════════════════════╤════════════════════════╕
│sim │gate │
╞════════════════════╪════════════════════════╡
│(:X {name: "sim 1"})│(:Gate {name: "gate a"})│
├────────────────────┼────────────────────────┤
│(:X {name: "sim 2"})│(:Gate {name: "gate a"})│
├────────────────────┼────────────────────────┤
│(:X {name: "sim 2"})│(:Gate {name: "gate b"})│
├────────────────────┼────────────────────────┤
│(:X {name: "sim 3"})│(:Gate {name: "gate a"})│
├────────────────────┼────────────────────────┤
│(:X {name: "sim 3"})│(:Gate {name: "gate b"})│
├────────────────────┼────────────────────────┤
│(:X {name: "sim 3"})│(:Gate {name: "gate c"})│
└────────────────────┴────────────────────────┘