Skip to content

Commit 1d9a96a

Browse files
JPryce-Aklundhrsill-neo4jNataliaIvakinarenetapopovarecrwplay
authored
2025.08 release (#1377)
Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: Richard Sill <[email protected]> Co-authored-by: NataliaIvakina <[email protected]> Co-authored-by: Reneta Popova <[email protected]> Co-authored-by: Neil Dewhurst <[email protected]> Co-authored-by: Stefano Ottolenghi <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Nadja Müller <[email protected]> Co-authored-by: Therese Magnusson <[email protected]> Co-authored-by: Wilco <[email protected]> Co-authored-by: JoelBergstrand <[email protected]> Co-authored-by: Gem Lamont <[email protected]> Co-authored-by: Arne Fischereit <[email protected]> Co-authored-by: Richard Sill <[email protected]> Co-authored-by: Lidia Zuin <[email protected]> Co-authored-by: Hannes Voigt <[email protected]> Co-authored-by: hvub <[email protected]>
1 parent db4f856 commit 1d9a96a

File tree

14 files changed

+1293
-547
lines changed

14 files changed

+1293
-547
lines changed

antora.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ nav:
77
- modules/ROOT/content-nav.adoc
88
asciidoc:
99
attributes:
10-
neo4j-version: '2025.07'
10+
neo4j-version: '2025.08'

modules/ROOT/images/graph-predicate-functions.svg

Lines changed: 37 additions & 37 deletions
Loading

modules/ROOT/images/predicate-function-example.svg

Lines changed: 0 additions & 12 deletions
This file was deleted.

modules/ROOT/pages/clauses/listing-functions.adoc

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -254,19 +254,17 @@ WHERE name STARTS WITH 'a'
254254
|===
255255
| name | isBuiltIn
256256

257-
| "abs" | true
258-
| "abs" | true
259-
| "acos" | true
260-
| "all" | true
261-
| "any" | true
262-
| "asin" | true
263-
| "atan" | true
257+
| "abs" | true
258+
| "acos" | true
259+
| "all" | true
260+
| "allReduce" | true
261+
| "any" | true
262+
| "asin" | true
263+
| "atan" | true
264264
| "atan2" | true
265-
| "avg" | true
266-
| "avg" | true
267-
| "avg" | true
265+
| "avg" | true
268266

269-
2+d|Rows: 11
267+
2+d|Rows: 9
270268
|===
271269

272270

modules/ROOT/pages/clauses/match.adoc

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -639,10 +639,26 @@ RETURN relationshipType, count(r) AS relationshipCount
639639
[[dynamic-match-caveats]]
640640
=== Performance caveats
641641

642-
`MATCH` queries using dynamic values may not be as performant as those using static values.
643-
This is because the xref:planning-and-tuning/execution-plans.adoc[Cypher planner] uses statically available information when planning queries to determine whether to use an xref:indexes/search-performance-indexes/index.adoc[index] or not, and this is not possible when using dynamic values.
642+
`MATCH` queries that use dynamic values may not perform as well as those with static values.
643+
Neo4j is actively working to improve the performance of these queries.
644+
The table below outlines performance caveats for specific Neo4j versions.
644645

645-
As a result, `MATCH` queries using dynamic values cannot leverage xref:planning-and-tuning/operators/operators-detail.adoc#leaf-operators[index scans or seeks] and must instead use the xref:planning-and-tuning/operators/operators-detail.adoc#query-plan-all-nodes-scan[`AllNodesScan`] operator, which reads all nodes from the node store and is therefore more costly.
646+
.Neo4j versions and performance caveats
647+
[%header,cols="a,5a"]
648+
|===
649+
| Neo4j versions | Performance caveat
650+
651+
| 5.26 -- 2025.07
652+
| The xref:planning-and-tuning/execution-plans.adoc[Cypher planner] is not able to leverage xref:indexes/search-performance-indexes/index.adoc[indexes] with xref:planning-and-tuning/operators/operators-detail.adoc#leaf-operators[index scans or seeks] and must instead utilize the xref:planning-and-tuning/operators/operators-detail.adoc#query-plan-all-nodes-scan[`AllNodesScan`] operator, which reads all nodes from the node store and is therefore more costly.
653+
654+
| 2025.08 -- current
655+
| The Cypher planner is able to leverage xref:indexes/search-performance-indexes/using-indexes.adoc#token-lookup-indexes[token lookup indexes] when matching node labels and relationship types dynamically.
656+
This is enabled by the introduction of three new query plan operators:
657+
xref:planning-and-tuning/operators/operators-detail.adoc#query-plan-dynamic-label-node-lookup[`DynamicLabelNodeLookup`], xref:planning-and-tuning/operators/operators-detail.adoc#query-plan-dynamic-directed-relationship-type-lookup[`DynamicDirectedRelationshipTypeLookup`], and xref:planning-and-tuning/operators/operators-detail.adoc#query-plan-dynamic-undirected-relationship-type-lookup[`DynamicUndirectedRelationshipTypeLookup`].
658+
It is not, however, able to use indexes on property values.
659+
For example, `MATCH (n:$(Label) {foo: bar})` will not use any indexes on `n.foo` but can use a `DynamicLabelNodeLookup` on `$(label)`.
660+
661+
|===
646662

647663
[[further-reading]]
648664
=== Further reading

modules/ROOT/pages/clauses/merge.adoc

Lines changed: 15 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -740,42 +740,23 @@ RETURN greta.name AS name, labels(greta) AS labels, type(rel) AS relType, collec
740740
[[dynamic-merge-caveats]]
741741
=== Performance caveats
742742

743-
`MERGE` queries that use dynamic values may not be as performant as those using static values.
744-
This is because the xref:planning-and-tuning/execution-plans.adoc[Cypher planner] uses statically available information when planning queries to determine whether to use an xref:indexes/search-performance-indexes/index.adoc[index] or not, and this is not possible when using dynamic values.
743+
`MERGE` queries that use dynamic values may not perform as well as those with static values.
744+
Neo4j is actively working to improve the performance of these queries.
745+
The table below outlines performance caveats for specific Neo4j versions.
745746

746-
As a result, `MERGE` queries with dynamic values cannot leverage xref:planning-and-tuning/operators/operators-detail.adoc#leaf-operators[index scans or seeks] and must instead use the xref:planning-and-tuning/operators/operators-detail.adoc#query-plan-all-nodes-scan[`AllNodesScan`] operator, which reads all nodes from the node store and is therefore more costly.
747-
748-
To circumvent possible performance issues, place the dynamic labels or relationship types within `ON CREATE` or `ON MATCH` subclauses.
749-
750-
.Parameters
751-
[source, parameters]
752-
----
753-
{
754-
"onMatchLabels": ["Filmmaker", "AwardRecipient"],
755-
"onCreateLabels": ["ScreenWriter", "AwardWinner"]
756-
}
757-
----
758-
759-
.Merge nodes using dynamic values in `ON CREATE` and `ON MATCH` subclauses
760-
[source, cypher]
761-
----
762-
MERGE (n:Person {name: "Greta Gerwig"})
763-
ON MATCH
764-
SET n:$($onMatchLabels)
765-
ON CREATE
766-
SET n:$($onCreateLabels)
767-
RETURN labels(n) AS gretaLabels
768-
----
769-
770-
Because a `Person` node with the `name` "Greta Gerwig" already exists, this query will only `SET` the dynamic labels added to the `ON MATCH` subclause.
771-
772-
.Result
773-
[role="queryresult",options="footer",cols="1*<m"]
747+
.Neo4j versions and performance caveats
748+
[%header,cols="a,5a"]
774749
|===
775-
| gretaLabels
750+
| Neo4j versions | Performance caveat
776751

777-
| ["Person", "Director", "Filmmaker", "AwardRecipient"]
752+
| 5.26 -- 2025.07
753+
| The xref:planning-and-tuning/execution-plans.adoc[Cypher planner] is not able to leverage xref:indexes/search-performance-indexes/index.adoc[indexes] with xref:planning-and-tuning/operators/operators-detail.adoc#leaf-operators[index scans or seeks] and must instead utilize the xref:planning-and-tuning/operators/operators-detail.adoc#query-plan-all-nodes-scan[`AllNodesScan`] operator, which reads all nodes from the node store and is therefore more costly.
778754

779-
1+d|Rows: 1
780-
|===
755+
| 2025.08 -- current
756+
| The Cypher planner is able to leverage xref:indexes/search-performance-indexes/using-indexes.adoc#token-lookup-indexes[token lookup indexes] when matching node labels and relationship types dynamically.
757+
This is enabled by the introduction of three new query plan operators:
758+
xref:planning-and-tuning/operators/operators-detail.adoc#query-plan-dynamic-label-node-lookup[`DynamicLabelNodeLookup`], xref:planning-and-tuning/operators/operators-detail.adoc#query-plan-dynamic-directed-relationship-type-lookup[`DynamicDirectedRelationshipTypeLookup`], and xref:planning-and-tuning/operators/operators-detail.adoc#query-plan-dynamic-undirected-relationship-type-lookup[`DynamicUndirectedRelationshipTypeLookup`].
759+
It is not, however, able to use indexes on property values.
760+
For example, `MERGE (n:$(Label) {foo: bar})` will not use any indexes on `n.foo` but can use a `DynamicLabelNodeLookup` on `$(label)`.
781761

762+
|===

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

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,79 @@ 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+
=== Updated in Cypher 25
29+
30+
[cols="2", options="header"]
31+
|===
32+
| Feature
33+
| Details
34+
35+
a|
36+
label:functionality[]
37+
label:updated[]
38+
[source, cypher]
39+
----
40+
MATCH (p:Product) WHERE p.name <> "Coffee"
41+
CALL (p) {
42+
MATCH (p)<-[:BUYS]-(c:Customer)-[:BUYS]->(otherProduct)
43+
RETURN c, otherProduct
44+
NEXT
45+
RETURN count(DISTINCT c) AS customers, 0 AS customersAlsoBuyingCoffee
46+
UNION
47+
FILTER otherProduct.name = "Coffee"
48+
RETURN 0 as customers, count(DISTINCT c) AS customersAlsoBuyingCoffee
49+
NEXT
50+
RETURN max(customers) AS customers, max(customersAlsoBuyingCoffee) AS customersAlsoBuyingCoffee
51+
}
52+
RETURN p.name AS product,
53+
round(toFloat(customersAlsoBuyingCoffee) * 100 / customers, 1) AS percentageOfCustomersAlsoBuyingCoffee
54+
ORDER BY product
55+
----
56+
57+
| `NEXT` now correctly supports aggregations in the context of `UNION` and `CALL`.
58+
For more information, see xref:queries/composed-queries/sequential-queries.adoc#issues-fixes[Sequential queries (`NEXT`) > Known issues and fixes].
59+
60+
a|
61+
label:functionality[]
62+
label:updated[]
63+
[source, cypher]
64+
----
65+
PROFILE
66+
WITH "Person" AS label
67+
MATCH (people:$(label))
68+
RETURN people.name
69+
----
70+
71+
| Cypher can now leverage xref:indexes/search-performance-indexes/using-indexes.adoc#token-lookup-indexes[token lookup indexes] when planning queries with xref:clauses/match.adoc#dynamic-match[dynamic labels and relationship types].
72+
This is enabled by the introduction of three new query plan operators: xref:planning-and-tuning/operators/operators-detail.adoc#query-plan-dynamic-label-node-lookup[`DynamicLabelNodeLookup`], xref:planning-and-tuning/operators/operators-detail.adoc#query-plan-dynamic-directed-relationship-type-lookup[`DynamicDirectedRelationshipTypeLookup`], and xref:planning-and-tuning/operators/operators-detail.adoc#query-plan-dynamic-undirected-relationship-type-lookup[`DynamicUndirectedRelationshipTypeLookup`].
73+
|===
74+
75+
=== New in Cypher 25
76+
77+
[cols="2", options="header"]
78+
|===
79+
| Feature
80+
| Details
81+
82+
a|
83+
label:functionality[]
84+
label:new[]
85+
[source, cypher, role="noheader"]
86+
----
87+
MATCH (()-->(n))+
88+
WHERE allReduce(acc = 0, node IN n \| acc + node.x, 6 < acc < 30)
89+
RETURN [i IN n \| i.x] AS sequence
90+
ORDER BY head(n).x, size(n)
91+
----
92+
93+
| New xref:functions/predicate.adoc#functions-allreduce[`allReduce()`] function.
94+
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.
95+
|===
96+
97+
2598
[[cypher-deprecations-additions-removals-2025.07]]
2699
== Neo4j 2025.07
27100

modules/ROOT/pages/functions/index.adoc

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,12 @@ 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.
380+
Where that list is a group variable defined in a quantified path pattern, it allows for the early pruning of paths that do not satisfy the predicate. label:cypher[Cypher 25 only] label:new[Introduced in Neo4j 2025.08]
381+
377382
1.1+| xref::functions/predicate.adoc#functions-any[`any()`]
378383
| `any(variable :: ANY, list :: LIST<ANY>, predicate :: ANY) :: BOOLEAN`
379384
| Returns true if the predicate holds for at least one element in the given `LIST<ANY>`.

0 commit comments

Comments
 (0)