Suraja Hathi
Suraja Hathi

Reputation: 50

Neo4j : create a recursive query/function

☼ Hello !

I want to get the critical path of an activity list, but through Neo4j.

For this, I need the Earliest Times (Start and Finish). The Earliest Start of an activity equals the greatest Earliest Finish of its predecessors, and so on.

I already had something "working". But my problem is that I just need to "recall the function". I can go down by hand, but I can't do it indefinitely...

The Activity List

Here is my code :

// LEVEL 1
/****** collect (start.successors) as startSucessors *****/
MATCH (project:Project)-[:CONTAINS]->(:Activity{tag:'Start'})-[s:ENABLES]->(:Activity) 
WHERE ID(project)=toInteger(322)
WITH collect(endNode(s)) AS startSuccessors
    /**** foreach node in startSucessors ****/
    UNWIND startSuccessors AS node
    /**** collect (node.predecessors) as nodePredecessors ****/
        MATCH (activity:Activity)-[p:ENABLES]->(node)
        WITH collect(startNode(p)) AS nodePredecessors, node, startSuccessors
            /**** foreach activity in nodePredecessors ****/
            UNWIND nodePredecessors AS activity
                /**** IF (node.ES is null OR node.ES < activity.EF) ****/
                WITH node, activity, startSuccessors,(node.ES = 0) AS cond1, (node.ES < activity.EF) AS cond2 
                MERGE (activity)-[:ENABLES]->(node)
                ON MATCH SET  node.ES =
                  CASE
                    /**if**/ WHEN cond1 OR cond2 
                    /**node.ES = activity.EF**/ THEN activity.EF
                      END
                ON MATCH SET node.EF = node.ES + node.ET
     // LEVEL 2
     /**T.O.D.O. : loop for each node in startSuccessors and their nodes **/
     WITH startSuccessors
     UNWIND  startSuccessors AS node
        MERGE (node)-[s2:ENABLES]->(successor:Activity)
        WITH collect(successor) AS nodeSuccessors,node
        UNWIND nodeSuccessors AS successor 
            CREATE UNIQUE (act:Activity)-[p2:ENABLES]->(successor)
            WITH successor, node,act, (successor.ES = 0) AS cond3, (successor.ES < act.EF) AS cond4
            MERGE (act)-[p2:ENABLES]->(successor)
            ON MATCH SET  successor.ES =
                  CASE
                    /**if**/ WHEN cond3 OR cond4 
                    /**node.ES = activity.EF**/ THEN act.EF
                      END
                ON MATCH SET successor.EF = successor.ES + successor.ET

Here is the result Earliest Times Query Result

The second problem is that if I rerun the query, the ES and EF properties disappear ... (prove below)

Problem when rerunning the query

To repair this, I have to run this query :

MATCH (p:Project) WHERE ID(p)=322
MATCH (p)-[:CONTAINS]->(one:Activity{tag:'one'}),(p)-[:CONTAINS]->(zrht:Activity{tag:'zrht'}),(p)-[:CONTAINS]->(ore:Activity{tag:'ore'}),(p)-[:CONTAINS]->(bam:Activity{tag:'bam'}),(p)-[:CONTAINS]->(two:Activity{tag:'two'})
SET one.EF = 0,one.ES = 0,one.LF=0,one.LS=0,zrht.EF = 0,zrht.ES = 0,zrht.LF=0,zrht.LS=0,ore.EF = 0,ore.ES = 0,ore.LF=0,ore.LS=0,bam.EF = 0,bam.ES = 0,bam.LF=0,bam.LS=0,two.EF = 0,two.ES = 0,two.LF=0,two.LS=0

This javascript code reaches what I want to do.

Thank you very much for your help.

Upvotes: 0

Views: 298

Answers (1)

Suraja Hathi
Suraja Hathi

Reputation: 50

☼ I finally found what I was looking for : Project Management with Neo4j

In hopes it will help other to find in a quicker way ;)

Upvotes: 1

Related Questions