Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
09-20-2018 03:26 AM
Hi!
I want to design a rule engine in Neo4j.
One type of rule is a "inclusion 1-way". If a prameter is included in the input it can give you another parameter which in turn can give another parameter etc. Parameters is a global object and the same parameter can be used in many different rules.
In below example both P1 and P2 is needed for rule1 to be valid.
Rule1 gives P3 which in rule 2 gives P5 and P6. But to get P8 we also need P7 to be chosen.
How do I make a good query to traverse the graph.
Script for creating above example
CREATE (p1:Param {id:"P1"})
CREATE (p2:Param {id:"P2"})
CREATE (p3:Param {id:"P3"})
CREATE (p4:Param {id:"P4"})
CREATE (p5:Param {id:"P5"})
CREATE (p6:Param {id:"P6"})
CREATE (p7:Param {id:"P7"})
CREATE (p8:Param {id:"P8"})
CREATE (p9:Param {id:"P9"})
CREATE (p10:Param {id:"P10"})
CREATE (r1:Regel {id:"REGEL1", type:"inclusion 1-way"})
CREATE (r1)-[:SELECT]->(p1)
CREATE (r1)-[:SELECT]->(p2)
CREATE (r1)-[:INCLUDE]->(p3)
CREATE (r1)-[:INCLUDE]->(p4)
CREATE (r2:Regel {id:"REGEL2", type:"inclusion 1-way"})
CREATE (r2)-[:SELECT]->(p3)
CREATE (r2)-[:INCLUDE]->(p5)
CREATE (r2)-[:INCLUDE]->(p6)
CREATE (r3:Regel {id:"REGEL3", type:"inclusion 1-way"})
CREATE (r3)-[:SELECT]->(p6)
CREATE (r3)-[:SELECT]->(p7)
CREATE (r3)-[:INCLUDE]->(p8)
This is what I've come up with so far for getting the first step
MATCH (p0:Param)<-[rel0:INCLUDE]-(r1:Regel)-[rel1:SELECT]->(p1:Param)
WHERE p1.id IN [ "P1","P2", "P7"] AND r1.type = "inclusion 1-way"
WITH (CASE WHEN COUNT(distinct p1)-SIZE((r1)-[:SELECT]-(:Param)) = 0 THEN 'ok' ELSE 'fel' END) AS check, r1.id AS rid, collect (distinct p0.id) AS incs
WHERE check = 'ok'
RETURN rid, incs
I would like it to return (regel1), P3,P4, (regel2), P5, P6, (regel3), P8 (even P8 since I have P7 as an input parameter).
09-21-2018 06:00 AM
So I have created this tree out of the above rules.
MATCH (r:Regel)-[rel]-(p:Param)
WHERE r.type = "inclusion 1-way"
WITH r AS rule,
CASE WHEN type(rel) = "SELECT" THEN p.id ELSE null END AS selpars,
CASE WHEN type(rel) = "INCLUDE" THEN p.id ELSE null END AS incpars
ORDER BY selpars, incpars
WITH rule AS rule, COLLECT(incpars) AS incpars, COLLECT(selpars) AS selpars
UNWIND(incpars) as incpar
WITH rule, selpars, nodes(incpar)
MERGE (t1:TreeNode {id:selpars})
MERGE (t2:TreeNode {id:incpar})
MERGE (t1)-[:NEXT_INCLUDE]->(t2)
MERGE (t1)-[:IN_RULE]->(rule)
Will give me this graph
If I have the in parameters P1,P2, P7 I should get P3, P4, P5, P6 and P8 (since P6,P7 implies P8).
How to write such a query?
If a add another node so that P4 implies P7. Then I will find P6 and P7 in the leafs which should imply that P8 should be included. How can I accomplish this?
CREATE (r4:Regel {id:"REGEL4", type:"inclusion 1-way"})
CREATE (r4)-[:SELECT]->(p4)
CREATE (r4)-[:INCLUDE]->(p7)
MATCH p=(t)-[r:NEXT_INCLUDE*]->() WHERE t.id = ["P1","P2"] RETURN p
╒═════════════════════════════════════════════════════════════╕
│"p" │
╞════════════════════════════════════════════════════════════╡
│[{"id":["P1","P2"]},{},{"id":["P3"]}] │
├────────────────────────────────────────────────────────────┤
│[{"id":["P1","P2"]},{},{"id":["P3"]},{"id":["P3"]},{},{"id":["P5"]}]│
├────────────────────────────────────────────────────────────┤
│[{"id":["P1","P2"]},{},{"id":["P3"]},{"id":["P3"]},{},{"id":["P6"]}]│
├────────────────────────────────────────────────────────────┤
│[{"id":["P1","P2"]},{},{"id":["P4"]}] │
├────────────────────────────────────────────────────────────┤
│[{"id":["P1","P2"]},{},{"id":["P4"]},{"id":["P4"]},{},{"id":["P7"]}]│
└────────────────────────────────────────────────────────────┘
All the sessions of the conference are now available online