Skip to content

Commit c1bbb02

Browse files
initial
1 parent ebe0db3 commit c1bbb02

File tree

3 files changed

+145
-17
lines changed

3 files changed

+145
-17
lines changed

modules/ROOT/pages/deprecations-additions-removals-compatibility.adoc

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,33 @@ Cypher 25 was introduced in Neo4j 2025.06 and can only be used on Neo4j 2025.06+
2222
Features removed in Cypher 25 are still available on Neo4j 2025.06+ databases either by prepending a query with `CYPHER 5` or by having Cypher 5 as the default language for the database.
2323
For more information, see xref:queries/select-version.adoc[].
2424

25+
[[cypher-deprecations-additions-removals-2025.08]]
26+
== Neo4j 2025.08
27+
28+
=== New in Cypher 25
29+
30+
[cols="2", options="header"]
31+
|===
32+
| Feature
33+
| Details
34+
35+
a|
36+
label:functionality[]
37+
label:new[]
38+
[source, cypher, role="noheader"]
39+
----
40+
MATCH (()-->(n))+
41+
WHERE allReduce(acc = 0, node IN n \| acc + node.x, 6 < acc < 30)
42+
RETURN [i IN n \| i.x] AS sequence
43+
ORDER BY head(n).x, size(n)
44+
----
45+
46+
| New xref:functions/predicate.adoc#functions-allreduce[`allReduce()`] function.
47+
It enables the stepwise evaluation of a value accumulated over a path, allowing for early pruning of paths that do not satisfy a given predicate, and is optimized for path expansions.
48+
49+
|===
50+
51+
2552
[[cypher-deprecations-additions-removals-2025.07]]
2653
== Neo4j 2025.07
2754

modules/ROOT/pages/functions/index.adoc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,11 @@ These functions return either true or false for the given arguments.
373373
1.1+| xref::functions/predicate.adoc#functions-all[`all()`]
374374
| `all(variable :: ANY, list :: LIST<ANY>, predicate :: ANY) :: BOOLEAN`
375375
| Returns true if the predicate holds for all elements in the given `LIST<ANY>`.
376-
376+
377+
1.1+| xref::functions/predicate.adoc#functions-allreduce[`allReduce()`]
378+
| `allReduce(accumulator = initial, stepVariable IN list \| reductionFunction, predicate) :: BOOLEAN`
379+
| Returns true if, during the stepwise evaluation of a value across the elements in a given `LIST<ANY>`, the accumulated result satisfies a specified predicate at every step, allowing for the early pruning of paths that do not meet the predicate. label:new[Introduced in Neo4j 2025.08]
380+
377381
1.1+| xref::functions/predicate.adoc#functions-any[`any()`]
378382
| `any(variable :: ANY, list :: LIST<ANY>, predicate :: ANY) :: BOOLEAN`
379383
| Returns true if the predicate holds for at least one element in the given `LIST<ANY>`.

modules/ROOT/pages/functions/predicate.adoc

Lines changed: 113 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,21 @@ To recreate it, run the following query against an empty Neo4j database:
1919

2020
[source, cypher, role=test-setup]
2121
----
22-
CREATE
23-
(keanu:Person {name:'Keanu Reeves', age:58, nationality:'Canadian'}),
24-
(carrie:Person {name:'Carrie Anne Moss', age:55, nationality:'American'}),
25-
(liam:Person {name:'Liam Neeson', age:70, nationality:'Northern Irish'}),
26-
(guy:Person {name:'Guy Pearce', age:55, nationality:'Australian'}),
27-
(kathryn:Person {name:'Kathryn Bigelow', age:71, nationality:'American'}),
28-
(jessica:Person {name:'Jessica Chastain', age:45, address:''}),
29-
(theMatrix:Movie {title:'The Matrix'}),
30-
(keanu)-[:KNOWS]->(carrie),
31-
(keanu)-[:KNOWS]->(liam),
32-
(keanu)-[:KNOWS]->(kathryn),
33-
(kathryn)-[:KNOWS]->(jessica),
34-
(carrie)-[:KNOWS]->(guy),
35-
(liam)-[:KNOWS]->(guy),
36-
(keanu)-[:ACTED_IN]->(theMatrix),
37-
(carrie)-[:ACTED_IN]->(theMatrix)
22+
CREATE (keanu:Person {name:'Keanu Reeves', age:58, nationality:'Canadian'}),
23+
(carrie:Person {name:'Carrie Anne Moss', age:55, nationality:'American'}),
24+
(liam:Person {name:'Liam Neeson', age:70, nationality:'Northern Irish'}),
25+
(guy:Person {name:'Guy Pearce', age:55, nationality:'Australian'}),
26+
(kathryn:Person {name:'Kathryn Bigelow', age:71, nationality:'American'}),
27+
(jessica:Person {name:'Jessica Chastain', age:45, address:''}),
28+
(theMatrix:Movie {title:'The Matrix'}),
29+
(keanu)-[:KNOWS {since:1999}]->(carrie),
30+
(keanu)-[:KNOWS {since:2005}]->(liam),
31+
(keanu)-[:KNOWS {since:2010}]->(kathryn),
32+
(kathryn)-[:KNOWS {since:2012}]->(jessica),
33+
(carrie)-[:KNOWS {since:2008}]->(guy),
34+
(liam)-[:KNOWS {since:2009}]->(guy),
35+
(keanu)-[:ACTED_IN]->(theMatrix),
36+
(carrie)-[:ACTED_IN]->(theMatrix);
3837
----
3938

4039
[[functions-all]]
@@ -107,7 +106,105 @@ RETURN all(i in emptyList WHERE true) as allTrue, all(i in emptyList WHERE false
107106
108107
======
109108

109+
[[functions-allreduce]]
110+
[role=label--new-2025.08]
111+
== allReduce()
110112

113+
.Details
114+
|===
115+
| *Syntax* 3+| `allReduce(accumulator = initial, stepVariable IN list \| reductionFunction, predicate)`
116+
| *Description* 3+| Returns true if, during the stepwise evaluation of a value across the elements in a given LIST<ANY>, the accumulated result satisfies a specified predicate at every step, allowing for the early pruning of paths that do not meet the predicate.
117+
.7+| *Arguments* | *Name* | *Type* | *Description*
118+
| `accumulator` | `ANY` | A variable that holds the result of the `reductionFunction` as the `list` is iterated.
119+
It is initialized with the value of `initial`.
120+
| `initial` | `ANY` | The value of the `accumulator` for the first evaluation of `reductionFunction`.
121+
| `stepVariable` | `ANY` | A variable that holds the value of each element of `list` during iteration.
122+
| `list` | `LIST<ANY>` | The list that is being iterated over.
123+
| `reductionFunction` | `ANY` | An expression whose return value becomes the next value of the `accumulator`.
124+
The return type must match the return type of `initial`.
125+
| `predicate` | `BOOLEAN` | A predicate that is evaluated for each iteration.
126+
It has access to the variable `accumulator`, but not `stepVariable`.
127+
| *Returns* 3+| `BOOLEAN`
128+
|===
129+
130+
.Considerations
131+
|===
132+
| `allReduce()` differs from most Cypher functions because it iterates over a list, evaluating an expression for each element, rather than returning a result from a single evaluation.
133+
| `allReduce()` combines the functionality of the xref:functions/predicate.adoc#functions-all[`all()`] and xref:functions/list.adoc#functions-reduce[`reduce()`] functions.
134+
| If all evaluations of `predicate` are `true`, `allReduce()` will return `true`.
135+
| If any evaluations of `predicate` are `false`, `allReduce()` will return `false`.
136+
| `allReduce()` returns `true` if `list` is empty because there are no elements to falsify the `predicate`.
137+
|===
138+
139+
.allReduce()
140+
======
141+
142+
`allReduce()` is designed to optimize path expansions.
143+
144+
The below query finds `KNOWS` paths with a length of `3` where the cumulative age stays between `60` and `180`.
145+
Paths exceeding this range at any step are pruned.
146+
For example, a path starting with a node whose `age` value is less than `60` is automatically excluded, as is a path with a sequence such as `["Liam Neeson (70)", "Keanu Reeves (58)", "Kathryn Bigelow (71)"]` because its aggregated `age` value exceeds `180`.
147+
148+
.Find aggregated ages within a boundary
149+
// tag::functions_predicate_allreduce_boundary[]
150+
[source, cypher]
151+
----
152+
MATCH (()-[:KNOWS]-(n)){3}
153+
WHERE allReduce(
154+
acc = 0,
155+
node IN n | acc + node.age,
156+
60 < acc < 180)
157+
RETURN [i IN n | i.name || " (" + toString(i.age) || ")"] AS ageSequence,
158+
reduce(acc = 0, node IN n | acc + node.age) AS aggregatedAges
159+
ORDER BY head(n).age
160+
----
161+
// end::functions_predicate_allreduce_boundary[]
162+
163+
.Result
164+
[role="queryresult",options="header,footer",cols="2*<m"]
165+
|===
166+
| ageSequence | aggregatedAges
167+
168+
| ["Liam Neeson (70)", "Guy Pearce (55)", "Jessica Chastain (45)"] | 170
169+
| ["Kathryn Bigelow (71)", "Jessica Chastain (45)", "Guy Pearce (55)"] | 171
170+
171+
2+d|Rows: 2
172+
|===
173+
174+
The next query uses `alReduce()` to compare neighboring relationships.
175+
It finds KNOWS paths with a length of at least `3` where each relationship’s `since` value is greater than the previous one and above `2000`.
176+
Paths are pruned if any since value fails these conditions.
177+
178+
.Find paths where a relationship property must be above a value and increase along a path
179+
// tag::functions_predicate_allreduce_relationship_values[]
180+
[source, cypher]
181+
----
182+
MATCH path = ()-[r:KNOWS]-{3,}()
183+
WHERE allReduce(
184+
span = {},
185+
rel IN r | { previous: span.current, current: rel.since },
186+
(span.previous IS NULL OR span.previous < span.current) AND span.current > 2000
187+
)
188+
LET people = nodes(path)
189+
RETURN [actor IN people | actor.name] AS connectedActors,
190+
[rel IN r | rel.since] AS sinceYears
191+
----
192+
// end::functions_predicate_allreduce_relationship_values[]
193+
194+
.Result
195+
[role="queryresult",options="header,footer",cols="2*<m"]
196+
|===
197+
| connectedActors | sinceYears
198+
199+
| ["Keanu Reeves", "Liam Neeson", "Guy Pearce", "Jessica Chastain"] | [2005, 2009, 2015]
200+
| ["Keanu Reeves", "Kathryn Bigelow", "Jessica Chastain", "Guy Pearce"] | [2010, 2012, 2015]
201+
| ["Liam Neeson", "Keanu Reeves", "Kathryn Bigelow", "Jessica Chastain"] | [2005, 2010, 2012]
202+
| ["Liam Neeson", "Keanu Reeves", "Kathryn Bigelow", "Jessica Chastain", "Guy Pearce"] | [2005, 2010, 2012, 2015]
203+
204+
2+d|Rows: 4
205+
|===
206+
207+
======
111208
[[functions-any]]
112209
== any()
113210

0 commit comments

Comments
 (0)