From f84991c1a1c4000656006e8278a57b980aaab36d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20Pryce-=C3=85klundh?= <112686610+JPryce-Aklundh@users.noreply.github.com> Date: Thu, 14 Aug 2025 08:57:08 +0200 Subject: [PATCH 1/7] initial --- ...ions-additions-removals-compatibility.adoc | 24 +++++++++++++++++++ .../operators/operators-detail.adoc | 12 ++++++++++ 2 files changed, 36 insertions(+) diff --git a/modules/ROOT/pages/deprecations-additions-removals-compatibility.adoc b/modules/ROOT/pages/deprecations-additions-removals-compatibility.adoc index 51b7133a9..13654e544 100644 --- a/modules/ROOT/pages/deprecations-additions-removals-compatibility.adoc +++ b/modules/ROOT/pages/deprecations-additions-removals-compatibility.adoc @@ -22,6 +22,30 @@ Cypher 25 was introduced in Neo4j 2025.06 and can only be used on Neo4j 2025.06+ 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. For more information, see xref:queries/select-version.adoc[]. +[[cypher-deprecations-additions-removals-2025.08]] +== Neo4j 2025.08 + +=== Updated in Cypher 25 + +[cols="2", options="header"] +|=== +| Feature +| Details + +a| +label:functionality[] +label:updated[] +[source, cypher] +---- + +---- + +| Dynamic labels and relationship types can leverage xref:indexes/search-performance-indexes/using-indexes.adoc#token-lookup-indexes[token lookup indexes]. +This is enables by the introduction of three new query plan operators: xref:planning-and-tuning/operators/operators-detail.adoc#query-plan-dynamic-node-label-lookup[`DynamicNodeLabelLookup`], 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`]. + +|=== + + [[cypher-deprecations-additions-removals-2025.07]] == Neo4j 2025.07 diff --git a/modules/ROOT/pages/planning-and-tuning/operators/operators-detail.adoc b/modules/ROOT/pages/planning-and-tuning/operators/operators-detail.adoc index dc2ba7f93..7c54e13ae 100644 --- a/modules/ROOT/pages/planning-and-tuning/operators/operators-detail.adoc +++ b/modules/ROOT/pages/planning-and-tuning/operators/operators-detail.adoc @@ -2576,6 +2576,18 @@ Total database accesses: 106 ====== +[role=label--new-2025.08] +[[query-plan-dynamic-node-label-lookup]] +== Dynamic Node Label Lookup + +[role=label--new-2025.08] +[[query-plan-dynamic-directed-relationship-type-lookup]] +== Dynamic Directed Relationship Type Lookup + +[role=label--new-2025.08] +[[query-plan-dynamic-undirected-relationship-type-lookup]] +== Dynamic Undirected Relationship Type Lookup + [[nested-loops-join-operators]] == Nested loops and join operators From d8c377eaeaa3a48963d9206ee3c0e7b4c22fe4ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20Pryce-=C3=85klundh?= <112686610+JPryce-Aklundh@users.noreply.github.com> Date: Thu, 14 Aug 2025 11:42:30 +0200 Subject: [PATCH 2/7] query plan --- modules/ROOT/pages/clauses/match.adoc | 22 +++- modules/ROOT/pages/clauses/merge.adoc | 24 +++- ...ions-additions-removals-compatibility.adoc | 7 +- .../operators/operators-detail.adoc | 124 ++++++++++++++++++ 4 files changed, 168 insertions(+), 9 deletions(-) diff --git a/modules/ROOT/pages/clauses/match.adoc b/modules/ROOT/pages/clauses/match.adoc index 7c491ffdb..b6386ad08 100644 --- a/modules/ROOT/pages/clauses/match.adoc +++ b/modules/ROOT/pages/clauses/match.adoc @@ -639,10 +639,26 @@ RETURN relationshipType, count(r) AS relationshipCount [[dynamic-match-caveats]] === Performance caveats -`MATCH` queries using dynamic values may not be as performant as those using static values. -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. +`MATCH` queries that use dynamic values may not perform as well as those with static values. +Neo4j is actively working to improve the performance of these queries. +The table below outlines performance caveats for specific Neo4j versions. -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. +.Neo4j versions and performance caveats +[%header,cols="a,5a"] +|=== +| Neo4j versions | Performance caveat + +| 5.26 -- 2025.07 +| xref:planning-and-tuning/execution-plans.adoc[Cypher planner] 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. + +| 2025.08 -- current +| Cypher planner is able to leverage leverage xref:indexes/search-performance-indexes/using-indexes.adoc#token-lookup-indexes[token lookup indexes] when matching node labels and relationship types dynamically. +This is enabled by the introduction of three new query plan operators: +xref:planning-and-tuning/operators/operators-detail.adoc#query-plan-dynamic-node-label-lookup[`DynamicNodeLabelLookup`], 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`]. +It is not, however, able to indexes on property values. +For example, `MATCH (n:$(Label) {foo: bar})` will not use any indexes on `n.foo`. + +|=== [[further-reading]] === Further reading diff --git a/modules/ROOT/pages/clauses/merge.adoc b/modules/ROOT/pages/clauses/merge.adoc index b244c19b9..71cc85add 100644 --- a/modules/ROOT/pages/clauses/merge.adoc +++ b/modules/ROOT/pages/clauses/merge.adoc @@ -740,12 +740,28 @@ RETURN greta.name AS name, labels(greta) AS labels, type(rel) AS relType, collec [[dynamic-merge-caveats]] === Performance caveats -`MERGE` queries that use dynamic values may not be as performant as those using static values. -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. +`MATCH` queries that use dynamic values may not perform as well as those with static values. +Neo4j is actively working to improve the performance of these queries. +The table below outlines performance caveats for specific Neo4j versions. -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. +.Neo4j versions and performance caveats +[%header,cols="a,5a"] +|=== +| Neo4j versions | Performance caveat + +| 5.26 -- 2025.07 +| xref:planning-and-tuning/execution-plans.adoc[Cypher planner] 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. + +| 2025.08 -- current +| Cypher planner is able to leverage leverage xref:indexes/search-performance-indexes/using-indexes.adoc#token-lookup-indexes[token lookup indexes] when matching node labels and relationship types dynamically. +This is enabled by the introduction of three new query plan operators: +xref:planning-and-tuning/operators/operators-detail.adoc#query-plan-dynamic-node-label-lookup[`DynamicNodeLabelLookup`], 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`]. +It is not, however, able to indexes on property values. +For example, `MERGE (n:$(Label) {foo: bar})` will not use any indexes on `n.foo`. + +|=== -To circumvent possible performance issues, place the dynamic labels or relationship types within `ON CREATE` or `ON MATCH` subclauses. +If you are using Neo4j 5.26 -- 2025.07, you can circumvent the inability of the Cypher planner to leverage token lookup indexes by placing the dynamic labels or relationship types within `ON CREATE` or `ON MATCH` subclauses. .Parameters [source, parameters] diff --git a/modules/ROOT/pages/deprecations-additions-removals-compatibility.adoc b/modules/ROOT/pages/deprecations-additions-removals-compatibility.adoc index 13654e544..39be88817 100644 --- a/modules/ROOT/pages/deprecations-additions-removals-compatibility.adoc +++ b/modules/ROOT/pages/deprecations-additions-removals-compatibility.adoc @@ -37,10 +37,13 @@ label:functionality[] label:updated[] [source, cypher] ---- - +PROFILE +WITH "Person" AS label +MATCH (people:$(label)) +RETURN people.name ---- -| Dynamic labels and relationship types can leverage xref:indexes/search-performance-indexes/using-indexes.adoc#token-lookup-indexes[token lookup indexes]. +| xref:clauses/match.adoc#dynamic-match[Dynamic labels and relationship types] can now leverage xref:indexes/search-performance-indexes/using-indexes.adoc#token-lookup-indexes[token lookup indexes]. This is enables by the introduction of three new query plan operators: xref:planning-and-tuning/operators/operators-detail.adoc#query-plan-dynamic-node-label-lookup[`DynamicNodeLabelLookup`], 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`]. |=== diff --git a/modules/ROOT/pages/planning-and-tuning/operators/operators-detail.adoc b/modules/ROOT/pages/planning-and-tuning/operators/operators-detail.adoc index 7c54e13ae..540cecb3a 100644 --- a/modules/ROOT/pages/planning-and-tuning/operators/operators-detail.adoc +++ b/modules/ROOT/pages/planning-and-tuning/operators/operators-detail.adoc @@ -2580,14 +2580,138 @@ Total database accesses: 106 [[query-plan-dynamic-node-label-lookup]] == Dynamic Node Label Lookup +Allows Cypher to use xref:indexes/search-performance-indexes/using-indexes.adoc#token-lookup-indexes[token lookup indexes] when planning queries using xref:clauses/match.adoc#dynamic-match[dynamic node labels]. + +.DynamicNodeLabelLookup +====== + +.Query +[source, cypher] +---- +PROFILE +WITH "Person" AS label +MATCH (people:$(label)) +RETURN people.name +---- + +.Query Plan +[role="queryplan", subs="attributes+"] +---- +Planner COST + +Runtime PIPELINED + +Runtime version {neo4j-version} + +Batch size 128 + + ++---------------------------+----+------------------------------+----------------+------+---------+----------------+------------------------+-----------+---------------------+ +| Operator | Id | Details | Estimated Rows | Rows | DB Hits | Memory (Bytes) | Page Cache Hits/Misses | Time (ms) | Pipeline | ++---------------------------+----+------------------------------+----------------+------+---------+----------------+------------------------+-----------+---------------------+ +| +ProduceResults | 0 | `people.name` | 26 | 14 | 0 | 0 | | | | +| | +----+------------------------------+----------------+------+---------+----------------+ | | | +| +Projection | 1 | people.name AS `people.name` | 26 | 14 | 28 | | | | | +| | +----+------------------------------+----------------+------+---------+----------------+ | | | +| +Apply | 2 | | 26 | 14 | 0 | | | | | +| |\ +----+------------------------------+----------------+------+---------+----------------+ | | | +| | +DynamicLabelNodeLookup | 3 | people:$all(label) | 26 | 14 | 15 | 1832 | 2/0 | 0.366 | Fused in Pipeline 1 | +| | +----+------------------------------+----------------+------+---------+----------------+------------------------+-----------+---------------------+ +| +Projection | 4 | $autostring_0 AS label | 1 | 1 | 0 | | | | Fused in Pipeline 0 | ++---------------------------+----+------------------------------+----------------+------+---------+----------------+------------------------+-----------+---------------------+ +---- +====== + [role=label--new-2025.08] [[query-plan-dynamic-directed-relationship-type-lookup]] == Dynamic Directed Relationship Type Lookup +Allows Cypher to use xref:indexes/search-performance-indexes/using-indexes.adoc#token-lookup-indexes[token lookup indexes] when planning queries using xref:clauses/match.adoc#dynamic-match[dynamic relationship types] in directed relationship patterns. + +.DynamicDirectedRelationshipTypeLookup +====== + +.Query +[source, cypher] +---- +PROFILE +WITH "FRIENDS_WITH" AS relType +MATCH ()-[r:$(relType)]->() +RETURN count(r) as relCount +---- + +.Query Plan +[role="queryplan", subs="attributes+"] +---- +Planner COST + +Runtime PIPELINED + +Runtime version {neo4j-version} + +Batch size 128 + ++------------------------------------------+----+--------------------------+----------------+------+---------+----------------+------------------------+-----------+---------------------+ +| Operator | Id | Details | Estimated Rows | Rows | DB Hits | Memory (Bytes) | Page Cache Hits/Misses | Time (ms) | Pipeline | ++------------------------------------------+----+--------------------------+----------------+------+---------+----------------+------------------------+-----------+---------------------+ +| +ProduceResults | 0 | relCount | 1 | 1 | 0 | 0 | 0/0 | 0.022 | In Pipeline 2 | +| | +----+--------------------------+----------------+------+---------+----------------+------------------------+-----------+---------------------+ +| +EagerAggregation | 1 | count(r) AS relCount | 1 | 1 | 0 | 40 | | | | +| | +----+--------------------------+----------------+------+---------+----------------+ | | | +| +Apply | 2 | | 21 | 12 | 0 | | | | | +| |\ +----+--------------------------+----------------+------+---------+----------------+ | | | +| | +DynamicDirectedRelationshipTypeLookup | 3 | ()-[r:$all(relType)]->() | 21 | 12 | 13 | 1968 | 2/0 | 0.359 | Fused in Pipeline 1 | +| | +----+--------------------------+----------------+------+---------+----------------+------------------------+-----------+---------------------+ +| +Projection | 4 | $autostring_0 AS relType | 1 | 1 | 0 | | | | Fused in Pipeline 0 | ++------------------------------------------+----+--------------------------+----------------+------+---------+----------------+------------------------+-----------+---------------------+ +---- +====== + + [role=label--new-2025.08] [[query-plan-dynamic-undirected-relationship-type-lookup]] == Dynamic Undirected Relationship Type Lookup +Allows Cypher to use xref:indexes/search-performance-indexes/using-indexes.adoc#token-lookup-indexes[token lookup indexes] when planning queries using dynamic relationship types in undirected relationship patterns. + +.DynamicUndirectedRelationshipTypeLookup +====== + +.Query +[source, cypher] +---- +PROFILE +WITH "FRIENDS_WITH" AS relType +MATCH ()-[r:$(relType)]-() +RETURN count(r) as relCount +---- + +.Query Plan +[role="queryplan", subs="attributes+"] +---- +Planner COST + +Runtime PIPELINED + +Runtime version {neo4j-version} + +Batch size 128 + ++--------------------------------------------+----+--------------------------+----------------+------+---------+----------------+------------------------+-----------+---------------------+ +| Operator | Id | Details | Estimated Rows | Rows | DB Hits | Memory (Bytes) | Page Cache Hits/Misses | Time (ms) | Pipeline | ++--------------------------------------------+----+--------------------------+----------------+------+---------+----------------+------------------------+-----------+---------------------+ +| +ProduceResults | 0 | relCount | 1 | 1 | 0 | 0 | 0/0 | 0.011 | In Pipeline 2 | +| | +----+--------------------------+----------------+------+---------+----------------+------------------------+-----------+---------------------+ +| +EagerAggregation | 1 | count(r) AS relCount | 1 | 1 | 0 | 40 | | | | +| | +----+--------------------------+----------------+------+---------+----------------+ | | | +| +Apply | 2 | | 42 | 24 | 0 | | | | | +| |\ +----+--------------------------+----------------+------+---------+----------------+ | | | +| | +DynamicUndirectedRelationshipTypeLookup | 3 | ()-[r:$all(relType)]-() | 42 | 24 | 13 | 1968 | 2/0 | 0.121 | Fused in Pipeline 1 | +| | +----+--------------------------+----------------+------+---------+----------------+------------------------+-----------+---------------------+ +| +Projection | 4 | $autostring_0 AS relType | 1 | 1 | 0 | | | | Fused in Pipeline 0 | ++--------------------------------------------+----+--------------------------+----------------+------+---------+----------------+------------------------+-----------+---------------------+ +---- +====== [[nested-loops-join-operators]] == Nested loops and join operators From 5aae3d4ec54767784b4b7bbb8fb23ece8dbea3d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20Pryce-=C3=85klundh?= <112686610+JPryce-Aklundh@users.noreply.github.com> Date: Thu, 14 Aug 2025 11:44:15 +0200 Subject: [PATCH 3/7] mistake fix --- modules/ROOT/pages/clauses/merge.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ROOT/pages/clauses/merge.adoc b/modules/ROOT/pages/clauses/merge.adoc index 71cc85add..f8b425791 100644 --- a/modules/ROOT/pages/clauses/merge.adoc +++ b/modules/ROOT/pages/clauses/merge.adoc @@ -740,7 +740,7 @@ RETURN greta.name AS name, labels(greta) AS labels, type(rel) AS relType, collec [[dynamic-merge-caveats]] === Performance caveats -`MATCH` queries that use dynamic values may not perform as well as those with static values. +`MERGE` queries that use dynamic values may not perform as well as those with static values. Neo4j is actively working to improve the performance of these queries. The table below outlines performance caveats for specific Neo4j versions. From ca3b3fe0534e1d431727e01ad26d48c043489da6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20Pryce-=C3=85klundh?= <112686610+JPryce-Aklundh@users.noreply.github.com> Date: Thu, 14 Aug 2025 11:50:34 +0200 Subject: [PATCH 4/7] correct header levels --- .../planning-and-tuning/operators/operators-detail.adoc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/ROOT/pages/planning-and-tuning/operators/operators-detail.adoc b/modules/ROOT/pages/planning-and-tuning/operators/operators-detail.adoc index 540cecb3a..c2739793c 100644 --- a/modules/ROOT/pages/planning-and-tuning/operators/operators-detail.adoc +++ b/modules/ROOT/pages/planning-and-tuning/operators/operators-detail.adoc @@ -2578,7 +2578,7 @@ Total database accesses: 106 [role=label--new-2025.08] [[query-plan-dynamic-node-label-lookup]] -== Dynamic Node Label Lookup +=== Dynamic Node Label Lookup Allows Cypher to use xref:indexes/search-performance-indexes/using-indexes.adoc#token-lookup-indexes[token lookup indexes] when planning queries using xref:clauses/match.adoc#dynamic-match[dynamic node labels]. @@ -2624,7 +2624,7 @@ Batch size 128 [role=label--new-2025.08] [[query-plan-dynamic-directed-relationship-type-lookup]] -== Dynamic Directed Relationship Type Lookup +=== Dynamic Directed Relationship Type Lookup Allows Cypher to use xref:indexes/search-performance-indexes/using-indexes.adoc#token-lookup-indexes[token lookup indexes] when planning queries using xref:clauses/match.adoc#dynamic-match[dynamic relationship types] in directed relationship patterns. @@ -2670,7 +2670,7 @@ Batch size 128 [role=label--new-2025.08] [[query-plan-dynamic-undirected-relationship-type-lookup]] -== Dynamic Undirected Relationship Type Lookup +=== Dynamic Undirected Relationship Type Lookup Allows Cypher to use xref:indexes/search-performance-indexes/using-indexes.adoc#token-lookup-indexes[token lookup indexes] when planning queries using dynamic relationship types in undirected relationship patterns. From 14068d26dd9d128a5644a0e33761ec01bd284905 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20Pryce-=C3=85klundh?= <112686610+JPryce-Aklundh@users.noreply.github.com> Date: Thu, 14 Aug 2025 14:42:56 +0200 Subject: [PATCH 5/7] editorial and remove workaround example --- modules/ROOT/pages/clauses/match.adoc | 8 ++-- modules/ROOT/pages/clauses/merge.adoc | 45 +++---------------- ...ions-additions-removals-compatibility.adoc | 4 +- 3 files changed, 11 insertions(+), 46 deletions(-) diff --git a/modules/ROOT/pages/clauses/match.adoc b/modules/ROOT/pages/clauses/match.adoc index b6386ad08..9bcc8ad64 100644 --- a/modules/ROOT/pages/clauses/match.adoc +++ b/modules/ROOT/pages/clauses/match.adoc @@ -649,14 +649,14 @@ The table below outlines performance caveats for specific Neo4j versions. | Neo4j versions | Performance caveat | 5.26 -- 2025.07 -| xref:planning-and-tuning/execution-plans.adoc[Cypher planner] 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. +| 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. | 2025.08 -- current -| Cypher planner is able to leverage leverage xref:indexes/search-performance-indexes/using-indexes.adoc#token-lookup-indexes[token lookup indexes] when matching node labels and relationship types dynamically. +| 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. This is enabled by the introduction of three new query plan operators: xref:planning-and-tuning/operators/operators-detail.adoc#query-plan-dynamic-node-label-lookup[`DynamicNodeLabelLookup`], 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`]. -It is not, however, able to indexes on property values. -For example, `MATCH (n:$(Label) {foo: bar})` will not use any indexes on `n.foo`. +It is not, however, able to use indexes on property values. +For example, `MATCH (n:$(Label) {foo: bar})` will not use any indexes on `n.foo` but might use a `DynamicNodeLabelLookup` on `$(label)`. |=== diff --git a/modules/ROOT/pages/clauses/merge.adoc b/modules/ROOT/pages/clauses/merge.adoc index f8b425791..d1669b3bb 100644 --- a/modules/ROOT/pages/clauses/merge.adoc +++ b/modules/ROOT/pages/clauses/merge.adoc @@ -750,48 +750,13 @@ The table below outlines performance caveats for specific Neo4j versions. | Neo4j versions | Performance caveat | 5.26 -- 2025.07 -| xref:planning-and-tuning/execution-plans.adoc[Cypher planner] 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. +| 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. | 2025.08 -- current -| Cypher planner is able to leverage leverage xref:indexes/search-performance-indexes/using-indexes.adoc#token-lookup-indexes[token lookup indexes] when matching node labels and relationship types dynamically. +| 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. This is enabled by the introduction of three new query plan operators: xref:planning-and-tuning/operators/operators-detail.adoc#query-plan-dynamic-node-label-lookup[`DynamicNodeLabelLookup`], 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`]. -It is not, however, able to indexes on property values. -For example, `MERGE (n:$(Label) {foo: bar})` will not use any indexes on `n.foo`. - -|=== - -If you are using Neo4j 5.26 -- 2025.07, you can circumvent the inability of the Cypher planner to leverage token lookup indexes by placing the dynamic labels or relationship types within `ON CREATE` or `ON MATCH` subclauses. - -.Parameters -[source, parameters] ----- -{ - "onMatchLabels": ["Filmmaker", "AwardRecipient"], - "onCreateLabels": ["ScreenWriter", "AwardWinner"] -} ----- - -.Merge nodes using dynamic values in `ON CREATE` and `ON MATCH` subclauses -[source, cypher] ----- -MERGE (n:Person {name: "Greta Gerwig"}) -ON MATCH - SET n:$($onMatchLabels) -ON CREATE - SET n:$($onCreateLabels) -RETURN labels(n) AS gretaLabels ----- - -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. - -.Result -[role="queryresult",options="footer",cols="1* Date: Thu, 14 Aug 2025 14:44:40 +0200 Subject: [PATCH 6/7] can not might --- modules/ROOT/pages/clauses/match.adoc | 2 +- modules/ROOT/pages/clauses/merge.adoc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/ROOT/pages/clauses/match.adoc b/modules/ROOT/pages/clauses/match.adoc index 9bcc8ad64..05b22c52d 100644 --- a/modules/ROOT/pages/clauses/match.adoc +++ b/modules/ROOT/pages/clauses/match.adoc @@ -656,7 +656,7 @@ The table below outlines performance caveats for specific Neo4j versions. This is enabled by the introduction of three new query plan operators: xref:planning-and-tuning/operators/operators-detail.adoc#query-plan-dynamic-node-label-lookup[`DynamicNodeLabelLookup`], 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`]. It is not, however, able to use indexes on property values. -For example, `MATCH (n:$(Label) {foo: bar})` will not use any indexes on `n.foo` but might use a `DynamicNodeLabelLookup` on `$(label)`. +For example, `MATCH (n:$(Label) {foo: bar})` will not use any indexes on `n.foo` but can use a `DynamicNodeLabelLookup` on `$(label)`. |=== diff --git a/modules/ROOT/pages/clauses/merge.adoc b/modules/ROOT/pages/clauses/merge.adoc index d1669b3bb..f4f7fef9a 100644 --- a/modules/ROOT/pages/clauses/merge.adoc +++ b/modules/ROOT/pages/clauses/merge.adoc @@ -757,6 +757,6 @@ The table below outlines performance caveats for specific Neo4j versions. This is enabled by the introduction of three new query plan operators: xref:planning-and-tuning/operators/operators-detail.adoc#query-plan-dynamic-node-label-lookup[`DynamicNodeLabelLookup`], 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`]. It is not, however, able to use indexes on property values. -For example, `MERGE (n:$(Label) {foo: bar})` will not use any indexes on `n.foo` but might use a `DynamicNodeLabelLookup` on `$(label)`. +For example, `MERGE (n:$(Label) {foo: bar})` will not use any indexes on `n.foo` but can use a `DynamicNodeLabelLookup` on `$(label)`. |=== \ No newline at end of file From 6d17ba445af56fec4adcba75f4e289fb720a1d5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20Pryce-=C3=85klundh?= <112686610+JPryce-Aklundh@users.noreply.github.com> Date: Thu, 14 Aug 2025 15:12:44 +0200 Subject: [PATCH 7/7] fix table --- .../pages/deprecations-additions-removals-compatibility.adoc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/ROOT/pages/deprecations-additions-removals-compatibility.adoc b/modules/ROOT/pages/deprecations-additions-removals-compatibility.adoc index ba6f34c8c..bdcd19156 100644 --- a/modules/ROOT/pages/deprecations-additions-removals-compatibility.adoc +++ b/modules/ROOT/pages/deprecations-additions-removals-compatibility.adoc @@ -54,6 +54,8 @@ This is enabled by the introduction of three new query plan operators: xref:plan | Feature | Details +a| +label:functionality[] label:new[] [source, cypher, role="noheader"] ----