39 lines
1.5 KiB
Plaintext
39 lines
1.5 KiB
Plaintext
// Dynamic Critical Path Analysis Query for Graph Visualization (Pure Cypher, Final & Performant)
|
|
// Collects all paths into a single list to ensure full graph rendering in Memgraph Lab.
|
|
|
|
// Parameter for the scenario ID
|
|
// Example: :scenario_id => 'parallel-process'
|
|
|
|
// 1. Find start nodes for the scenario
|
|
MATCH (start_node:Job)
|
|
OPTIONAL MATCH (start_node)<-[r_in:PRECEDES {scenario: $scenario_id}]-()
|
|
WITH start_node, r_in WHERE r_in IS NULL
|
|
MATCH (end_node:Job)
|
|
OPTIONAL MATCH (end_node)-[r_out:PRECEDES {scenario: $scenario_id}]->()
|
|
WITH start_node, end_node, r_out WHERE r_out IS NULL
|
|
|
|
// 2. Match all valid paths for the scenario
|
|
MATCH path = (start_node)-[rels:PRECEDES*]->(end_node)
|
|
WHERE ALL(r IN rels WHERE r.scenario = $scenario_id)
|
|
|
|
// 3. For each job in the path, calculate its effective duration
|
|
WITH path, nodes(path) AS jobs_on_path
|
|
UNWIND jobs_on_path AS job
|
|
OPTIONAL MATCH (:Scenario {id: $scenario_id})-[m:MODIFIES]->(job)
|
|
WITH
|
|
path,
|
|
COLLECT({
|
|
effective_duration: COALESCE(m.new_duration, job.base_duration)
|
|
}) AS jobs_with_deltas
|
|
|
|
// 4. Calculate total duration for each path
|
|
WITH
|
|
path,
|
|
REDUCE(totalDuration = 0, data IN jobs_with_deltas | totalDuration + data.effective_duration) AS total_duration
|
|
|
|
// 5. Collect all paths, ordered by total_duration, into a single list
|
|
WITH COLLECT({path: path, total_duration: total_duration}) AS paths_with_duration
|
|
UNWIND paths_with_duration AS p_wd
|
|
ORDER BY p_wd.total_duration DESC
|
|
RETURN COLLECT(p_wd.path) AS all_paths;
|