<p dir="auto">I'm trying to design a single query that creates a node including input/output links with possible linking to existing nodes. Creation stages are separated by cardinality reduction clauses using <code class="notranslate">LIMIT 1</code>. This method prevents creation of certain nodes in preceding <code class="notranslate">CREATE</code> clause,  however.</p>
<ul dir="auto">
<li>Neo4j version: 3.4.6</li>
<li>Operating system: macOs 10.13.6</li>
<li>API/Driver: Cypher in neo4j browser</li>
</ul>
<h3 dir="auto">Steps to reproduce</h3>
<ol dir="auto">
<li>Create a structure that next step is going to build upon:</li>
</ol>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="CREATE (m:Move {id: &quot;m1&quot;})
WITH m
UNWIND [{i: 0}, {i: 1}, {i: 2}] as p
CREATE (m)-[:OUT]-&gt;(:Position {id: p.i})"><pre class="notranslate"><code class="notranslate">CREATE (m:Move {id: "m1"})
WITH m
UNWIND [{i: 0}, {i: 1}, {i: 2}] as p
CREATE (m)-[:OUT]-&gt;(:Position {id: p.i})
</code></pre></div>
<ol start="2" dir="auto">
<li>Tie to output positions from previous step:</li>
</ol>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="CREATE (m:Move {id: &quot;m2&quot;})

WITH m
UNWIND [{pid: 0}, {pid: 1}] as i
MATCH (p:Position {id: i.pid})
CREATE (p)-[:IN]-&gt;(m)

WITH m LIMIT 1
UNWIND [{pid: 2, addr: &quot;street&quot;}] as i
MATCH (p:Position {id: i.pid})
MERGE (p)-[:IS_A]-&gt;(a:Place {id: i.addr})
CREATE (p)-[:IN]-&gt;(m)"><pre class="notranslate"><code class="notranslate">CREATE (m:Move {id: "m2"})

WITH m
UNWIND [{pid: 0}, {pid: 1}] as i
MATCH (p:Position {id: i.pid})
CREATE (p)-[:IN]-&gt;(m)

WITH m LIMIT 1
UNWIND [{pid: 2, addr: "street"}] as i
MATCH (p:Position {id: i.pid})
MERGE (p)-[:IS_A]-&gt;(a:Place {id: i.addr})
CREATE (p)-[:IN]-&gt;(m)
</code></pre></div>
<h3 dir="auto">Expected behavior</h3>
<p dir="auto">All positions are linked to m2 by IN edges.</p>
<p dir="auto"><a target="_blank" rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/936155/44881933-a0b1dd00-acb1-11e8-88aa-c6a1eb9453f7.png"><img src="https://user-images.githubusercontent.com/936155/44881933-a0b1dd00-acb1-11e8-88aa-c6a1eb9453f7.png" alt="correct" style="max-width: 100%;"></a></p>
<h3 dir="auto">Actual behavior</h3>
<p dir="auto">Position 1 is not linked.</p>
<p dir="auto"><a target="_blank" rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/936155/44881939-a4ddfa80-acb1-11e8-8734-b4dfcc8f3c11.png"><img src="https://user-images.githubusercontent.com/936155/44881939-a4ddfa80-acb1-11e8-8734-b4dfcc8f3c11.png" alt="wrong" style="max-width: 100%;"></a></p>
<p dir="auto">The problem seems to be in cardinality reducing <code class="notranslate">WITH m LIMIT 1</code> because it prevents creation of the link according to second map in first unwind (just to test – link is created when using <code class="notranslate">WITH m LIMIT 2</code> but that leads to duplicate link from second unwind of course). I could use <code class="notranslate">WITH distinct m</code> but that is more expensive construct.</p>
<p dir="auto">I do not think that WITH clause should have this "backward" effect so I consider it a bug for now. I would welcome an explanation if I'm wrong :)</p>
<p dir="auto">Thanks!</p>
<ul dir="auto">
<li>Neo4j version: 5.8.0-enterprise</li>
<li>Operating system: Ubuntu 20.04</li>
<li>API/Driver: Cypher</li>
<li><strong>Steps to reproduce</strong></li>
</ul>
<p dir="auto">Hello! While testing Neo4j in the movie graph, I came across an issue related to duplicated path patterns. Allow me to explain in a clearer manner:</p>
<p dir="auto">In the second query, the expected result should be 506. This is because all pairs (n0, n1) in the first query, satisfy the pattern defined in the second query.</p>
<p dir="auto">Similarly, in the third query, the expected result should also be 506. However, currently, it returns 64, which is the number of pairs (n0, n1) that have at least two edges in the movie graph.<br>
The issue here is that there is no constraint requiring the two relationships to be identical, and thus the expected result should still be 506.</p>
<p dir="auto">While I am uncertain if this behavior is a bug in Neo4j, it is worth noting that other graph databases (such as Memgraph) attempt to address this by returning an exception <code class="notranslate">Redeclaring variable: r1</code> for the second query.</p>
<p dir="auto">Would it is possible for you to further confirm and investigate this issue?<br>
One possible solution to address this issue is to implement a step during query compilation that removes duplicated path patterns for each pattern, and another solution is to throw an exception like other GDBs when encountering a redeclared variable for relation.</p>
<div class="highlight highlight-source-cypher notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="//:play movie-graph
MATCH (n0)-[r1]-(n1) RETURN COUNT (*)
=&gt; 506
MATCH (n0)-[r1]-(n1), (n1)-[r1]-(n0) RETURN COUNT (*)
=&gt; 0
MATCH (n0)-[]-(n1), (n1)-[]-(n0) RETURN COUNT (*)
=&gt;64"><pre class="notranslate"><span class="pl-c">//:play movie-graph</span>
<span class="pl-k">MATCH</span> (<span class="pl-smi">n0</span>)<span class="pl-c1">-</span><span class="pl-k">[</span><span class="pl-smi">r1</span><span class="pl-k">]</span><span class="pl-c1">-</span>(<span class="pl-smi">n1</span>) <span class="pl-k">RETURN</span> <span class="pl-c1">COUNT</span> (<span class="pl-k">*</span>)
<span class="pl-k">=&gt;</span> <span class="pl-c1">506</span>
<span class="pl-k">MATCH</span> (<span class="pl-smi">n0</span>)<span class="pl-c1">-</span><span class="pl-k">[</span><span class="pl-smi">r1</span><span class="pl-k">]</span><span class="pl-c1">-</span>(<span class="pl-smi">n1</span>), (<span class="pl-smi">n1</span>)<span class="pl-c1">-</span><span class="pl-k">[</span><span class="pl-smi">r1</span><span class="pl-k">]</span><span class="pl-c1">-</span>(<span class="pl-smi">n0</span>) <span class="pl-k">RETURN</span> <span class="pl-c1">COUNT</span> (<span class="pl-k">*</span>)
<span class="pl-k">=&gt;</span> <span class="pl-c1">0</span>
<span class="pl-k">MATCH</span> (<span class="pl-smi">n0</span>)<span class="pl-c1">-</span><span class="pl-k">[</span><span class="pl-k">]</span><span class="pl-c1">-</span>(<span class="pl-smi">n1</span>), (<span class="pl-smi">n1</span>)<span class="pl-c1">-</span><span class="pl-k">[</span><span class="pl-k">]</span><span class="pl-c1">-</span>(<span class="pl-smi">n0</span>) <span class="pl-k">RETURN</span> <span class="pl-c1">COUNT</span> (<span class="pl-k">*</span>)
<span class="pl-k">=&gt;</span><span class="pl-c1">64</span></pre></div>
<ul dir="auto">
<li>Expected behavior</li>
</ul>
<div class="highlight highlight-source-cypher notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="MATCH (n0)-[r1]-(n1), (n1)-[r1]-(n0) RETURN COUNT (*)
=&gt; 506
MATCH (n0)-[]-(n1), (n1)-[]-(n0) RETURN COUNT (*)
=&gt; 506"><pre class="notranslate"><span class="pl-k">MATCH</span> (<span class="pl-smi">n0</span>)<span class="pl-c1">-</span><span class="pl-k">[</span><span class="pl-smi">r1</span><span class="pl-k">]</span><span class="pl-c1">-</span>(<span class="pl-smi">n1</span>), (<span class="pl-smi">n1</span>)<span class="pl-c1">-</span><span class="pl-k">[</span><span class="pl-smi">r1</span><span class="pl-k">]</span><span class="pl-c1">-</span>(<span class="pl-smi">n0</span>) <span class="pl-k">RETURN</span> <span class="pl-c1">COUNT</span> (<span class="pl-k">*</span>)
<span class="pl-k">=&gt;</span> <span class="pl-c1">506</span>
<span class="pl-k">MATCH</span> (<span class="pl-smi">n0</span>)<span class="pl-c1">-</span><span class="pl-k">[</span><span class="pl-k">]</span><span class="pl-c1">-</span>(<span class="pl-smi">n1</span>), (<span class="pl-smi">n1</span>)<span class="pl-c1">-</span><span class="pl-k">[</span><span class="pl-k">]</span><span class="pl-c1">-</span>(<span class="pl-smi">n0</span>) <span class="pl-k">RETURN</span> <span class="pl-c1">COUNT</span> (<span class="pl-k">*</span>)
<span class="pl-k">=&gt;</span> <span class="pl-c1">506</span></pre></div>
<p dir="auto">or</p>
<div class="highlight highlight-source-cypher notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="MATCH (n0)-[r1]-(n1), (n1)-[r1]-(n0) RETURN COUNT (*)
=&gt; Exception: Redeclaring variable: r1.
MATCH (n0)-[]-(n1), (n1)-[]-(n0) RETURN COUNT (*)
=&gt; 506"><pre class="notranslate"><span class="pl-k">MATCH</span> (<span class="pl-smi">n0</span>)<span class="pl-c1">-</span><span class="pl-k">[</span><span class="pl-smi">r1</span><span class="pl-k">]</span><span class="pl-c1">-</span>(<span class="pl-smi">n1</span>), (<span class="pl-smi">n1</span>)<span class="pl-c1">-</span><span class="pl-k">[</span><span class="pl-smi">r1</span><span class="pl-k">]</span><span class="pl-c1">-</span>(<span class="pl-smi">n0</span>) <span class="pl-k">RETURN</span> <span class="pl-c1">COUNT</span> (<span class="pl-k">*</span>)
<span class="pl-k">=&gt;</span> <span class="pl-smi">Exception</span>: <span class="pl-smi">Redeclaring</span> <span class="pl-smi">variable</span>: <span class="pl-smi">r1</span>.
<span class="pl-k">MATCH</span> (<span class="pl-smi">n0</span>)<span class="pl-c1">-</span><span class="pl-k">[</span><span class="pl-k">]</span><span class="pl-c1">-</span>(<span class="pl-smi">n1</span>), (<span class="pl-smi">n1</span>)<span class="pl-c1">-</span><span class="pl-k">[</span><span class="pl-k">]</span><span class="pl-c1">-</span>(<span class="pl-smi">n0</span>) <span class="pl-k">RETURN</span> <span class="pl-c1">COUNT</span> (<span class="pl-k">*</span>)
<span class="pl-k">=&gt;</span> <span class="pl-c1">506</span></pre></div>