diff --git a/modules/ROOT/pages/patterns/shortest-paths.adoc b/modules/ROOT/pages/patterns/shortest-paths.adoc index e8d83f72e..9bab3cfd5 100644 --- a/modules/ROOT/pages/patterns/shortest-paths.adoc +++ b/modules/ROOT/pages/patterns/shortest-paths.adoc @@ -572,7 +572,7 @@ Without `CALL`, the planner does not know how many targets there are per source ---- PROFILE MATCH p = ANY SHORTEST - (source:N {trail: ["C", "C", "A", "C", "A", "B", "B", "B", "A"]})--+ + (source:N {trail: ["C", "C", "A", "C", "A", "B", "B", "B", "A"]})--{2,} (target:N {trail: ["A", "B", "C", "A", "B", "C", "A", "B", "C"]}) RETURN length(p) AS pathLength ---- @@ -593,27 +593,27 @@ It, therefore, must exhaust all possible target nodes before determining the sho .Query Plan [source, role="queryplan"] ---- -+-----------------------------------+----+----------------------------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+ -| Operator | Id | Details | Estimated Rows | Rows | DB Hits | Memory (Bytes) | Page Cache Hits/Misses | Time (ms) | Pipeline | -+-----------------------------------+----+----------------------------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+ -| +ProduceResults | 0 | `length(p)` | 19612941 | 1 | 0 | 0 | 0/0 | 0.027 | | -| | +----+----------------------------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+ | -| +Projection | 1 | length((source)-[anon_7*]-(target)) AS `length(p)` | 19612941 | 1 | 17 | | 9/0 | 0.036 | | -| | +----+----------------------------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+ | -| +StatefulShortestPath(All, Trail) | 2 | SHORTEST 1 (source) ((`anon_3`)-[`anon_4`]-(`anon_5`)){1, } (target) | 19612941 | 1 | 354292 | 64720328 | 85358/0 | 139.138 | In Pipeline 1 | -| | | | expanding from: source | | | | | | | | -| | | | inlined predicates: target.trail = $autolist_1 | | | | | | | | -| | | | target:N | | | | | | | | -| | +----+----------------------------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+ -| +Filter | 3 | source.trail = $autolist_0 | 4429 | 1 | 177146 | | | | | -| | +----+----------------------------------------------------------------------+----------------+-------+---------+----------------+ | | | -| +NodeByLabelScan | 4 | source:N | 88573 | 88573 | 88574 | 376 | 2128/0 | 42.628 | Fused in Pipeline 0 | -+-----------------------------------+----+----------------------------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+ - -Total database accesses: 620029, total allocated memory: 64720664 ++-----------------------------------+----+-------------------------------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+ +| Operator | Id | Details | Estimated Rows | Rows | DB Hits | Memory (Bytes) | Page Cache Hits/Misses | Time (ms) | Pipeline | ++-----------------------------------+----+-------------------------------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+ +| +ProduceResults | 0 | pathLength | 19612941 | 1 | 0 | 0 | 0/0 | 0.088 | | +| | +----+-------------------------------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+ | +| +Projection | 1 | length((source)-[anon_39*]-(target)) AS pathLength | 19612941 | 1 | 17 | | 9/0 | 0.091 | | +| | +----+-------------------------------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+ | +| +StatefulShortestPath(All, Trail) | 2 | SHORTEST 1 (source) ((`anon_35`)-[`anon_36`]-(`anon_37`)){2, } (target) | 19612941 | 1 | 354300 | 65608284 | 85662/0 | 158.664 | In Pipeline 1 | +| | | | expanding from: source | | | | | | | | +| | | | inlined predicates: target.trail = $autolist_1 | | | | | | | | +| | | | target:N | | | | | | | | +| | +----+-------------------------------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+ +| +Filter | 3 | source.trail = $autolist_0 | 4429 | 1 | 177146 | | | | | +| | +----+-------------------------------------------------------------------------+----------------+-------+---------+----------------+ | | | +| +NodeByLabelScan | 4 | source:N | 88573 | 88573 | 88574 | 376 | 1853/0 | 53.311 | Fused in Pipeline 0 | ++-----------------------------------+----+-------------------------------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+ + +Total database accesses: 620037, total allocated memory: 65608620 1 row -ready to start consuming query after 59 ms, results consumed after another 183 ms +ready to start consuming query after 45 ms, results consumed after another 214 ms ---- However, since each `trail` property is unique, rewriting the query to use a `CALL` subquery yields a more efficient plan. @@ -626,43 +626,43 @@ PROFILE MATCH (start:N {trail: ["C", "C", "A", "C", "A", "B", "B", "B", "A"]}), (end:N {trail: ["A", "B", "C", "A", "B", "C", "A", "B", "C"]}) CALL (start, end) { - MATCH p = ANY SHORTEST (start)--+(end) + MATCH p = ANY SHORTEST (start)--{2,}(end) RETURN p } RETURN length(p) AS pathLength ---- -The result is a significantly faster query (down from 59 to 9 milliseconds): +The result is a significantly faster query (down from 45 to 4 milliseconds): .Query Plan [source, role="queryplan"] ---- -+------------------------------------+----+----------------------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+ -| Operator | Id | Details | Estimated Rows | Rows | DB Hits | Memory (Bytes) | Page Cache Hits/Misses | Time (ms) | Pipeline | -+------------------------------------+----+----------------------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+ -| +ProduceResults | 0 | `length(p)` | 19612941 | 1 | 0 | 0 | 0/0 | 0.019 | | -| | +----+----------------------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+ | -| +Projection | 1 | length(p) AS `length(p)` | 19612941 | 1 | 0 | | 0/0 | 0.007 | | -| | +----+----------------------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+ | -| +Projection | 2 | (start)-[anon_14*]-(end) AS p | 19612941 | 1 | 17 | | 9/0 | 0.073 | | -| | +----+----------------------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+ | -| +StatefulShortestPath(Into, Trail) | 3 | ANY 1 (start) ((`anon_10`)-[`anon_11`]-(`anon_12`)){1, } (end) | 19612941 | 1 | 1936 | 990280 | 205/0 | 1.135 | In Pipeline 3 | -| | +----+----------------------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+ -| +CartesianProduct | 4 | | 19612941 | 1 | 0 | 9040 | | 0.131 | In Pipeline 2 | -| |\ +----+----------------------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+ -| | +Filter | 5 | end.trail = $autolist_1 | 22143 | 1 | 177146 | | | | | -| | | +----+----------------------------------------------------------------+----------------+-------+---------+----------------+ | | | -| | +NodeByLabelScan | 6 | end:N | 442865 | 88573 | 88574 | 392 | 2128/0 | 29.822 | Fused in Pipeline 1 | -| | +----+----------------------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+ -| +Filter | 7 | start.trail = $autolist_0 | 4429 | 1 | 177146 | | | | | -| | +----+----------------------------------------------------------------+----------------+-------+---------+----------------+ | | | -| +NodeByLabelScan | 8 | start:N | 88573 | 88573 | 88574 | 376 | 2128/0 | 40.743 | Fused in Pipeline 0 | -+------------------------------------+----+----------------------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+ - -Total database accesses: 533393, total allocated memory: 999592 ++------------------------------------+----+---------------------------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+ +| Operator | Id | Details | Estimated Rows | Rows | DB Hits | Memory (Bytes) | Page Cache Hits/Misses | Time (ms) | Pipeline | ++------------------------------------+----+---------------------------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+ +| +ProduceResults | 0 | pathLength | 19612941 | 1 | 0 | 0 | 0/0 | 0.080 | | +| | +----+---------------------------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+ | +| +Projection | 1 | length(p) AS pathLength | 19612941 | 1 | 0 | | 0/0 | 0.023 | | +| | +----+---------------------------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+ | +| +Projection | 2 | (start)-[anon_15*]-(end) AS p | 19612941 | 1 | 17 | | 9/0 | 0.063 | | +| | +----+---------------------------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+ | +| +StatefulShortestPath(Into, Trail) | 3 | SHORTEST 1 (start) ((`anon_11`)-[`anon_12`]-(`anon_13`)){2, } (end) | 19612941 | 1 | 1952 | 1337576 | 209/0 | 1.938 | In Pipeline 3 | +| | +----+---------------------------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+ +| +CartesianProduct | 4 | | 19612941 | 1 | 0 | 9040 | | 0.054 | In Pipeline 2 | +| |\ +----+---------------------------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+ +| | +Filter | 5 | end.trail = $autolist_1 | 22143 | 1 | 177146 | | | | | +| | | +----+---------------------------------------------------------------------+----------------+-------+---------+----------------+ | | | +| | +NodeByLabelScan | 6 | end:N | 442865 | 88573 | 88574 | 392 | 1853/0 | 44.047 | Fused in Pipeline 1 | +| | +----+---------------------------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+ +| +Filter | 7 | start.trail = $autolist_0 | 4429 | 1 | 177146 | | | | | +| | +----+---------------------------------------------------------------------+----------------+-------+---------+----------------+ | | | +| +NodeByLabelScan | 8 | start:N | 88573 | 88573 | 88574 | 376 | 1853/0 | 57.818 | Fused in Pipeline 0 | ++------------------------------------+----+---------------------------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+ + +Total database accesses: 533409, total allocated memory: 1346888 1 row -ready to start consuming query after 9 ms, results consumed after another 73 ms +ready to start consuming query after 4 ms, results consumed after another 106 ms ---- ====== @@ -683,14 +683,14 @@ CREATE CONSTRAINT unique_trail FOR (n:N) REQUIRE n.trail IS UNIQUE ---- This constraint will inform the planner of the uniqueness of `trail` values up front. -As a result, the simpler shortest path query (without a `CALL` subquery) will now generate a faster plan (using the `StatefulShortestPath(Into)`) operator with a cardinality of 1 for both the source and target nodes of the shortest path. +As a result, the simpler shortest path query (without a `CALL` subquery) will now generate a faster plan (using the `StatefulShortestPath(Into)` operator) with a cardinality of 1 for both the source and target nodes of the shortest path. .Find a shortest path between two nodes [source, cypher] ---- PROFILE MATCH p = ANY SHORTEST - (source:N {trail: ["C", "C", "A", "C", "A", "B", "B", "B", "A"]})--+ + (source:N {trail: ["C", "C", "A", "C", "A", "B", "B", "B", "A"]})--{2,} (target:N {trail: ["A", "B", "C", "A", "B", "C", "A", "B", "C"]}) RETURN length(p) AS pathLength ---- @@ -701,13 +701,13 @@ RETURN length(p) AS pathLength +------------------------------------+----+----------------------------------------------------------------------------------------------------+----------------+------+---------+----------------+------------------------+-----------+---------------+ | Operator | Id | Details | Estimated Rows | Rows | DB Hits | Memory (Bytes) | Page Cache Hits/Misses | Time (ms) | Pipeline | +------------------------------------+----+----------------------------------------------------------------------------------------------------+----------------+------+---------+----------------+------------------------+-----------+---------------+ -| +ProduceResults | 0 | `length(p)` | 1 | 1 | 0 | 0 | 0/0 | 0.034 | | +| +ProduceResults | 0 | pathLength | 1 | 1 | 0 | 0 | 0/0 | 0.058 | | | | +----+----------------------------------------------------------------------------------------------------+----------------+------+---------+----------------+------------------------+-----------+ | -| +Projection | 1 | length((source)-[anon_19*]-(target)) AS `length(p)` | 1 | 1 | 17 | | 9/0 | 0.057 | | +| +Projection | 1 | length((source)-[anon_55*]-(target)) AS pathLength | 1 | 1 | 17 | | 9/0 | 0.081 | | | | +----+----------------------------------------------------------------------------------------------------+----------------+------+---------+----------------+------------------------+-----------+ | -| +StatefulShortestPath(Into, Trail) | 2 | SHORTEST 1 (source) ((`anon_15`)-[`anon_16`]-(`anon_17`)){1, } (target) | 1 | 1 | 1936 | 990288 | 205/0 | 1.658 | In Pipeline 1 | +| +StatefulShortestPath(Into, Trail) | 2 | SHORTEST 1 (source) ((`anon_51`)-[`anon_52`]-(`anon_53`)){2, } (target) | 1 | 1 | 1952 | 1337568 | 209/0 | 2.213 | In Pipeline 1 | | | +----+----------------------------------------------------------------------------------------------------+----------------+------+---------+----------------+------------------------+-----------+---------------+ -| +MultiNodeIndexSeek | 3 | UNIQUE source:N(trail) WHERE trail = $autolist_0, UNIQUE target:N(trail) WHERE trail = $autolist_1 | 1 | 1 | 4 | 376 | 4/2 | 0.332 | In Pipeline 0 | +| +MultiNodeIndexSeek | 3 | UNIQUE source:N(trail) WHERE trail = $autolist_0, UNIQUE target:N(trail) WHERE trail = $autolist_1 | 1 | 1 | 4 | 376 | 1/5 | 0.400 | In Pipeline 0 | +------------------------------------+----+----------------------------------------------------------------------------------------------------+----------------+------+---------+----------------+------------------------+-----------+---------------+ Total database accesses: 1957, total allocated memory: 990608 @@ -722,7 +722,7 @@ ready to start consuming query after 48 ms, results consumed after another 3 ms === Limitations of enforcing a single source-target node pair Enforcing a single source-target node pair is not always preferable. -With one source and many targets, rewriting a shortest path query using a `CALL` subquery forces the planner to use `StatefulShortestPath(Into)`, which runs once per target node. +With one source and many targets, rewriting a shortest path query using a `CALL` subquery forces the planner to use either the `ShortestPath` or `StatefulShortestPath(Into)` operator, which runs once per target node. While this is efficient for a single pair, it can become slower as the number of targets increases because it forces the planner to traverse the graph for each individual pair of source-target nodes. In such cases, it may be more efficient to let the planner use `StatefulShortestPath(All)`, which expands across the graph once and returns all matches. @@ -736,7 +736,7 @@ Consider the following query, which does not specify a unique target node and ge ---- PROFILE MATCH p = ANY SHORTEST - (start:N {trail: ["C", "C", "A", "C", "A", "B", "B", "B", "A"]})--+ + (start:N {trail: ["C", "C", "A", "C", "A", "B", "B", "B", "A"]})--{2,} (end:N {level: 9}) RETURN count(*) AS pathCount ---- @@ -756,28 +756,28 @@ Due to the existence of multiple target nodes without a specified, unique proper .Query Plan [source, role="queryplan"] ---- -+-----------------------------------+----+------------------------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------+ -| Operator | Id | Details | Estimated Rows | Rows | DB Hits | Memory (Bytes) | Page Cache Hits/Misses | Time (ms) | Pipeline | -+-----------------------------------+----+------------------------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------+ -| +ProduceResults | 0 | `count(*)` | 1 | 1 | 0 | 0 | 0/0 | 0.015 | | -| | +----+------------------------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+ | -| +EagerAggregation | 1 | count(*) AS `count(*)` | 1 | 1 | 0 | 40 | 0/0 | 0.097 | In Pipeline 2 | -| | +----+------------------------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------+ -| +StatefulShortestPath(All, Trail) | 2 | SHORTEST 1 (start) ((`anon_3`)-[`anon_4`]-(`anon_5`)){1, } (end) | 8052 | 19682 | 373974 | 81274328 | 65235/0 | 330.475 | In Pipeline 1 | -| | | | expanding from: start | | | | | | | | -| | | | inlined predicates: end.level = $autoint_1 | | | | | | | | -| | | | end:N | | | | | | | | -| | +----+------------------------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------+ -| +NodeUniqueIndexSeek | 3 | UNIQUE start:N(trail) WHERE trail = $autolist_0 | 1 | 1 | 2 | 376 | 3/0 | 0.106 | In Pipeline 0 | -+-----------------------------------+----+------------------------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------+ - -Total database accesses: 373976, total allocated memory: 81274688 ++-----------------------------------+----+---------------------------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------+ +| Operator | Id | Details | Estimated Rows | Rows | DB Hits | Memory (Bytes) | Page Cache Hits/Misses | Time (ms) | Pipeline | ++-----------------------------------+----+---------------------------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------+ +| +ProduceResults | 0 | pathCount | 1 | 1 | 0 | 0 | 0/0 | 0.082 | | +| | +----+---------------------------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+ | +| +EagerAggregation | 1 | count(*) AS pathCount | 1 | 1 | 0 | 40 | 0/0 | 1.151 | In Pipeline 2 | +| | +----+---------------------------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------+ +| +StatefulShortestPath(All, Trail) | 2 | SHORTEST 1 (start) ((`anon_19`)-[`anon_20`]-(`anon_21`)){2, } (end) | 8052 | 19682 | 373982 | 82162292 | 65705/0 | 455.921 | In Pipeline 1 | +| | | | expanding from: start | | | | | | | | +| | | | inlined predicates: end.level = $autoint_1 | | | | | | | | +| | | | end:N | | | | | | | | +| | +----+---------------------------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------+ +| +NodeUniqueIndexSeek | 3 | UNIQUE start:N(trail) WHERE trail = $autolist_0 | 1 | 1 | 2 | 376 | 3/0 | 0.509 | In Pipeline 0 | ++-----------------------------------+----+---------------------------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------+ + +Total database accesses: 373984, total allocated memory: 82162652 1 row -ready to start consuming query after 40 ms, results consumed after another 331 ms +ready to start consuming query after 83 ms, results consumed after another 592 ms ---- -If the query is rewritten with a `CALL` subquery the planner will use `StatefulShortestPath(Into)` which performs separate traversals for each individual source-target node pairs. +If the query is rewritten with a `CALL` subquery the planner will use the `StatefulShortestPath(Into)` operator which performs separate traversals for each individual source-target node pairs. .Multi-target shortest path query rewritten with a `CALL` subquery [source, cypher] @@ -786,7 +786,7 @@ PROFILE MATCH (start:N {trail: ["C", "C", "A", "C", "A", "B", "B", "B", "A"]}), (end:N {level: 9}) CALL (start, end) { - MATCH p = ANY SHORTEST (start)--+(end) + MATCH p = ANY SHORTEST (start)--{2,}(end) RETURN p } RETURN count(*) AS pathCount @@ -798,25 +798,25 @@ RETURN count(*) AS pathCount +------------------------------------+----+----------------------------------------------------------------------------------------------------+----------------+-------+----------+----------------+------------------------+-----------+---------------+ | Operator | Id | Details | Estimated Rows | Rows | DB Hits | Memory (Bytes) | Page Cache Hits/Misses | Time (ms) | Pipeline | +------------------------------------+----+----------------------------------------------------------------------------------------------------+----------------+-------+----------+----------------+------------------------+-----------+---------------+ -| +ProduceResults | 0 | `count(*)` | 1 | 1 | 0 | 0 | 0/0 | 0.120 | | +| +ProduceResults | 0 | pathCount | 1 | 1 | 0 | 0 | 0/0 | 0.185 | | | | +----+----------------------------------------------------------------------------------------------------+----------------+-------+----------+----------------+------------------------+-----------+ | -| +EagerAggregation | 1 | count(*) AS `count(*)` | 1 | 1 | 0 | 40 | 0/0 | 0.172 | In Pipeline 2 | +| +EagerAggregation | 1 | count(*) AS pathCount | 1 | 1 | 0 | 40 | 0/0 | 1.571 | In Pipeline 2 | | | +----+----------------------------------------------------------------------------------------------------+----------------+-------+----------+----------------+------------------------+-----------+---------------+ -| +Projection | 2 | (start)-[anon_7*]-(end) AS p | 8052 | 19682 | 314930 | | 184197/0 | 35.430 | | +| +Projection | 2 | (start)-[anon_15*]-(end) AS p | 8052 | 19682 | 314930 | | 189543/0 | 67.007 | | | | +----+----------------------------------------------------------------------------------------------------+----------------+-------+----------+----------------+------------------------+-----------+ | -| +StatefulShortestPath(Into, Trail) | 3 | SHORTEST 1 (start) ((`anon_3`)-[`anon_4`]-(`anon_5`)){1, } (end) | 8052 | 19682 | 32672226 | 157866776 | 3588500/0 | 14200.424 | In Pipeline 1 | +| +StatefulShortestPath(Into, Trail) | 3 | SHORTEST 1 (start) ((`anon_11`)-[`anon_12`]-(`anon_13`)){2, } (end) | 8052 | 19682 | 32986690 | 221424672 | 3775866/0 | 22680.410 | In Pipeline 1 | | | +----+----------------------------------------------------------------------------------------------------+----------------+-------+----------+----------------+------------------------+-----------+---------------+ -| +MultiNodeIndexSeek | 4 | UNIQUE start:N(trail) WHERE trail = $autolist_0, RANGE INDEX end:N(level) WHERE level = $autoint_1 | 8052 | 19683 | 19686 | 376 | 108/0 | 4.014 | In Pipeline 0 | +| +MultiNodeIndexSeek | 4 | UNIQUE start:N(trail) WHERE trail = $autolist_0, RANGE INDEX end:N(level) WHERE level = $autoint_1 | 8052 | 19683 | 19686 | 376 | 57/0 | 12.979 | In Pipeline 0 | +------------------------------------+----+----------------------------------------------------------------------------------------------------+----------------+-------+----------+----------------+------------------------+-----------+---------------+ -Total database accesses: 33006842, total allocated memory: 157867272 +Total database accesses: 33321306, total allocated memory: 221425168 1 row -ready to start consuming query after 32 ms, results consumed after another 14244 ms +ready to start consuming query after 49 ms, results consumed after another 22774 ms ---- As the plan shows, in this scenario it is not more efficient to enforce a single source-target node pair. -On the contrary, doing so ensures that `StatefulShortestPath(Into)` is executed `19682` times, once for each source-target node pair, thereby generating a more expensive query. +On the contrary, doing so ensures that the `StatefulShortestPath(Into)` operator is executed `19682` times, once for each source-target node pair, thereby generating a more expensive query. ===== @@ -845,8 +845,7 @@ Or, when the estimated cardinality of the source and target nodes in a shortest * Selector is one of: `SHORTEST 1`, `ANY`, `ANY SHORTEST`, `ALL SHORTEST`, `SHORTEST GROUP`, or `SHORTEST 1 GROUP`. * There is only one relationship pattern. * If the pattern is a xref:patterns/variable-length-patterns.adoc#quantified-path-patterns[quantified path pattern] in the form of `\(()-[]-())`, or is a xref:patterns/variable-length-patterns.adoc#quantified-relationships[quantified-relationship], and it uses a filter that can be applied directly to the relationship. -* If the pattern is a quantified path pattern or a quantified relationship and the relationship pattern is directed, the lower bound of the xref:patterns/reference.adoc#quantifiers[quantifier] is 0 or 1. -If the relationship pattern is directed, the lower bound is 0. +* If the pattern is a quantified path pattern or a quantified relationship and the lower bound of the xref:patterns/reference.adoc#quantifiers[quantifier] is 0 or 1. * In the case of a quantified path pattern, there are no node variables declared inside the quantified path pattern that are referenced elsewhere. | `StatefulShortestPath(Into)`