Skip to content

Conversation

@JPryce-Aklundh
Copy link
Collaborator

@JPryce-Aklundh JPryce-Aklundh commented Aug 14, 2025

Applies to both Cypher 5 and Cypher 25

Copy link
Contributor

@arnefischereit arnefischereit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some syntactical changes. But I guess the most relevant feedback is on the workaround for MERGE which was there even before this change.

| 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.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
| 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.
| 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.

| 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.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
| 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.
| 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.

| 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.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
It is not, however, able to indexes on property values.
It is not, however, able to use indexes on property values.

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`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
For example, `MATCH (n:$(Label) {foo: bar})` will not use any indexes on `n.foo`.
For example, `MATCH (n:$(label) {foo: bar})` will not use any indexes on `n.foo` but might use a `DynamicNodeLabelLookup` on `$(label)`.

|===

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.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know this "workaround" has been there before but I do not see that particular example helping:

If you have a static label Label, then

MERGE (n:Person:$($dynamicLabels) {name: "Greta Gerwig"})

should plan a label scan on :Person and then add a filter on :$($dynamicLabels) without ON .... But if you want to add other labels depending on MATCH or MERGE behaviour, you will need to use the ON ... anyway.

RETURN people.name
----

| 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].
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find it a bit odd from the wording to read that the labels/types are leveraging the indexes. I my mind, the execution engine (or the planner) is leveraging indexes to answer queries with dynamic labels/types. But maybe this is splitting hairs.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I think what I wrote is too ambiguous. Will update.

| 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.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
| 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.
| 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.

| 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.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
| 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.
| 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.

| 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.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
It is not, however, able to indexes on property values.
It is not, however, able to use indexes on property values.

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`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
For example, `MERGE (n:$(Label) {foo: bar})` will not use any indexes on `n.foo`.
For example, `MERGE (n:$(label) {foo: bar})` will not use any indexes on `n.foo` but might use a `DynamicNodeLabelLookup` on `$(label)`.

@neo4j-docops-agent
Copy link
Collaborator

neo4j-docops-agent commented Aug 14, 2025

Thanks for the documentation updates.

The preview documentation has now been torn down - reopening this PR will republish it.

@JPryce-Aklundh JPryce-Aklundh merged commit 5efacb1 into neo4j:dev Aug 14, 2025
5 checks passed
@JPryce-Aklundh JPryce-Aklundh deleted the dynamic_operators branch August 14, 2025 13:19
| 2025.08 -- current
| 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`].

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm afraid this is incorrect - the operator is called DynamicLabelNodeLookup!

JPryce-Aklundh added a commit to JPryce-Aklundh/docs-cypher that referenced this pull request Sep 2, 2025
Applies to both Cypher 5 and Cypher 25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants