As @FrankPavageau stated, coding the solution in Java may be less cumbersome and faster. Nevertheless, by taking advantage of the existing APOC procedure apoc.periodic.commit, you do not have to implement anything in Java.
apoc.periodic.commit
will repeatedly execute a Cypher query until it returns a value of 0 or no results at all. Here is an example of how to use it to solve your problem.
First, let's create your sample data:
CREATE (a:Foo {id: 'a'}), (b:Foo {id: 'b'}), (c:Foo {id: 'c'}), (d:Foo {id: 'd'}), (e:Foo {id: 'e'}), (f:Foo {id: 'f'}), (g:Foo {id: 'g'}),
(a)-[:NEXT {value: 3}]->(b),
(a)-[:NEXT {value: 4}]->(e),
(e)-[:NEXT {value: 3}]->(c),
(e)-[:NEXT {value: 1}]->(f),
(e)-[:NEXT {value: 2}]->(g),
(c)-[:NEXT {value: 3}]->(d),
(c)-[:NEXT {value: 2}]->(g);
This technique involves 3 queries on your part:
A query to create a temporary node with the Temp
label (to persist state between the repeated executions performed in step 2, below, and to hold the final results). (In the sample data, the starting node has an id
of a
.)
MERGE (temp:Temp)
SET temp = {values: [], ids: ['a']};
A query to call apoc.periodic.commit
to perform repeated executions of the passed Cypher statement. Each time that Cypher statement is executed, it starts from the last-found node (the one whose id
is at the tail end of temp.ids
), and attempts to find the next node whose relationship has the highest value
value. If the last node was a leaf node, then the Cypher statement returns nothing (since the second MATCH
will fail, aborting the statement) -- which will terminate the procedure; otherwise, the Cypher statement will append the max
value to temp.values
and the corresponding node id
to temp.ids
, and return 1.
CALL apoc.periodic.commit("
MATCH (temp:Temp)
MATCH (:Foo {id: LAST(temp.ids)})-[n:NEXT]->(f:Foo)
WITH temp, REDUCE(s = {max: 0}, x IN COLLECT({v: n.value, id: f.id}) |
CASE WHEN x.v > s.max
THEN {max: x.v, id: x.id}
ELSE s
END
) AS curr
SET temp.values = temp.values + curr.max, temp.ids = temp.ids + curr.id
RETURN 1;
", NULL);
A query to get the final results. The ids
collection will be the ids of the nodes along the "maximum path", and the values
collection will be the values
of the NEXT
relationships along that same path.
MATCH (temp:Temp)
RETURN temp;
Here is the result:
╒══════════════════════════════════════╕
│temp │
╞══════════════════════════════════════╡
│{values: [4, 3, 3], ids: [a, e, c, d]}│
└──────────────────────────────────────┘