<p dir="auto">Neo4j Version: 3.0.4</p>
<p dir="auto">Objective of the below query is to eliminate duplicate bus service and bustop in a path, it work fine if i didn't provide the relationship count <strong>-[r:CONNECTSWITH]-&gt;</strong> but if the relationship count defined <em><em>-[r:CONNECTSWITH</em>..3]-&gt;</em>* ,then its throwing</p>
<p dir="auto"><code class="notranslate">Key not found: r</code></p>
<p dir="auto"><strong>Working:</strong></p>
<p dir="auto"><code class="notranslate">OPTIONAL  MATCH p=(o:PORT{name:"busstop1"})-[r:CONNECTSWITH]-&gt;(d:PORT{name:"busstop2"}) where  ALL(r1 in rels(p) WHERE 1=size(filter(r2 in rels(p)where(r1.service=r2.service)))) and ALL(n in nodes(p) where 1=size(filter(m in nodes(p) WHERE id(m)=id(n))))  RETURN p  limit 10</code></p>
<p dir="auto"><strong>Not Working:</strong></p>
<p dir="auto"><code class="notranslate">OPTIONAL  MATCH p=(o:PORT{name:"busstop1"})-[r:CONNECTSWITH*..3]-&gt;(d:PORT{name:"busstop2"}) where  ALL(r1 in rels(p) WHERE 1=size(filter(r2 in rels(p)where(r1.service=r2.service)))) and ALL(n in nodes(p) where 1=size(filter(m in nodes(p) WHERE id(m)=id(n))))  RETURN p  limit 10</code></p>
<p dir="auto"><strong>Is your feature request related to a problem? Please describe.</strong></p>
<p dir="auto">For better indexing, I'd like to increment a property on a node everytime a relationship is merged and decrement the same property everytime the relationship gets deleted.</p>
<p dir="auto">Here is an example:</p>
<p dir="auto">If I understand correctly, the following <code class="notranslate">MERGE</code> query effectively sets the properties ONLY ONCE on create, even on concurrent writes <a href="https://neo4j.com/developer/kb/understanding-how-merge-works/#_merge_acquires_locks_on_nodes_and_relationships_in_the_pattern_when_resulting_in_pattern_creation" rel="nofollow">by locking the bound nodes and the relationship</a>.</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="MATCH (p:Post{id:$postId})
MATCH (u:User{id:$userId})
MERGE (u)-[up:UPVOTED_POST]-&gt;(p)
ON CREATE SET p.numberOfUpvotes = p.numberOfUpvotes + 1
RETURN p, u"><pre class="notranslate"><code class="notranslate">MATCH (p:Post{id:$postId})
MATCH (u:User{id:$userId})
MERGE (u)-[up:UPVOTED_POST]-&gt;(p)
ON CREATE SET p.numberOfUpvotes = p.numberOfUpvotes + 1
RETURN p, u
</code></pre></div>
<p dir="auto">And to reproduce same behavior and decrement with <code class="notranslate">DELETE</code>, I've only found the following solution to work using <a href="https://neo4j.com/labs/apoc/4.1/overview/apoc.lock/apoc.lock.nodes/" rel="nofollow">apoc.lock.nodes</a>:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="MATCH (p:Post{id:$postId})
MATCH (u:User{id:$userId})
CALL apoc.lock.nodes([p, u])
MATCH (u)-[up:UPVOTED_POST]-&gt;(p)
DELETE up
SET p.numberOfUpvotes = p.numberOfUpvotes - 1
RETURN p, u"><pre class="notranslate"><code class="notranslate">MATCH (p:Post{id:$postId})
MATCH (u:User{id:$userId})
CALL apoc.lock.nodes([p, u])
MATCH (u)-[up:UPVOTED_POST]-&gt;(p)
DELETE up
SET p.numberOfUpvotes = p.numberOfUpvotes - 1
RETURN p, u
</code></pre></div>
<p dir="auto">Without apoc.lock.nodes, concurrent writes will decrement the p.numberOfUpvotes property twice, resulting in an unreliable way to count the upvotes. This is because on concurrent writes, the <code class="notranslate">MATCH (u)-[up:UPVOTED_POST]-&gt;(p)</code> clause will effectively match in each concurrent query, the <code class="notranslate">DELETE up</code> clause will effectively return an empty <code class="notranslate">up</code> object in each concurrent query (so it's not possible to use that in a reliable way to conditionnally set the numberOfUpvotes) and the <code class="notranslate">SET p.numberOfUpvotes = p.numberOfUpvotes - 1</code> clause will effectively decrement <code class="notranslate">p.numberOfUpvotes</code> twice. Thus, <code class="notranslate">CALL apoc.lock.nodes([p, u])</code> or another approach to lock bound nodes is needed.</p>
<p dir="auto"><strong>Describe the solution you'd like</strong></p>
<p dir="auto"><a href="https://neo4j.com/developer/kb/understanding-how-merge-works/#_merge_acquires_locks_on_nodes_and_relationships_in_the_pattern_when_resulting_in_pattern_creation" rel="nofollow">Similar to <code class="notranslate">MERGE</code></a>, When <code class="notranslate">DELETE</code> is used on a relationship, it would acquire locks on all bound nodes and relationships in the pattern (on <code class="notranslate">u</code>, <code class="notranslate">up</code> and <code class="notranslate">p</code> in my example queries) before deleting the relationship.</p>
<p dir="auto"><strong>Describe alternatives you've considered</strong></p>
<p dir="auto">Before finding the <code class="notranslate">CALL apoc.lock.nodes([p, u])</code> solution, I thought about an <code class="notranslate">ON DELETE SET syntax</code>:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="MATCH (p:Post{id:$postId})
MATCH (u:User{id:$userId})
OPTIONAL MATCH (u)-[up:UPVOTED_POST]-&gt;(p)
DELETE up
ON DELETE SET p.numberOfUpvotes = p.numberOfUpvotes - 1
RETURN p"><pre class="notranslate"><code class="notranslate">MATCH (p:Post{id:$postId})
MATCH (u:User{id:$userId})
OPTIONAL MATCH (u)-[up:UPVOTED_POST]-&gt;(p)
DELETE up
ON DELETE SET p.numberOfUpvotes = p.numberOfUpvotes - 1
RETURN p
</code></pre></div>
<p dir="auto">The <code class="notranslate">ON DELETE</code> could be the syntax to add locks on bound nodes and relationships.</p>
<p dir="auto"><strong>Additional context</strong><br>
Understanding the issue at play and finding the <code class="notranslate">CALL apoc.lock.nodes([p, u])</code> solution took me about 3 days and a bit of luck. If this feature can't be implemented for reasons I didn't consider, it would be nice to have the workaround documented somewhere, at least on stack-overflow.</p>