title: Best way to combine Neo4j cypher queries (alternative to UNION)?
body: <p><strong>Given Model</strong></p>
  
  <p>There is a model with categories and relations between them.
  For relations, it can be specified, if they are bound to specific start or end categories.</p>
  
  <p>The are four types of relations:</p>
  
  <ul>
  <li>Only the start category is specified (ex.: "Outgoing")</li>
  <li>Only the end category is specified (ex.: "Incoming")</li>
  <li>Both, start and end categories are specified (ex.: "Outgoing and Incoming")</li>
  <li>Neither start nor end category is specified (ex.: "Unbound")</li>
  </ul>
  
  <p>Code:</p>
  
  <pre><code>MERGE (cat:ModelCategory {title:'Cat'})
  MERGE (rel1:ModelRelation {title:'Outgoing'})
  MERGE (rel2:ModelRelation {title:'Incoming'})
  MERGE (rel3:ModelRelation {title:'Outgoing and Incoming'})
  MERGE (rel4:ModelRelation {title:'Unbound'})
  MERGE (rel1)-[:STARTS_AT]-&gt;(cat)
  MERGE (rel2)-[:ENDS_AT]-&gt;(cat)
  MERGE (rel3)-[:STARTS_AT]-&gt;(cat)
  MERGE (rel3)-[:ENDS_AT]-&gt;(cat)
  </code></pre>
  
  <p><a href="http://i.stack.imgur.com/98qM7.png" rel="nofollow">Neo4j Browser Screenshot</a></p>
  
  <p><strong>Single queries</strong></p>
  
  <p>If you choose "Cat" as a start node and want to know, which relations and resulting end nodes can be created, you can use single queries:</p>
  
  <pre><code>// Relations with current source and a target
  // Returns relation "Outgoing and Incoming"
  MATCH (relation:ModelRelation)-[STARTS_AT]-&gt;(:ModelCategory{title:"Cat"}),
  (relation)-[ENDS_AT]-&gt;(target)
  RETURN DISTINCT relation, target
  
  // Relations with current source and without target
  // Returns relation "Outgoing"
  MATCH (relation:ModelRelation)-[STARTS_AT]-&gt;(:ModelCategory{title:"Cat"})
  WHERE NOT (relation)-[:ENDS_AT]-&gt;()
  MATCH (allCategories:ModelCategory)
  RETURN relation, allCategories as target
  
  // Relations with target, without source
  // Returns relation "Incoming"
  MATCH (relation:ModelRelation)-[ENDS_AT]-&gt;(target)
  WHERE NOT (relation)-[:STARTS_AT]-&gt;()
  RETURN relation, target
  
  // Relations without source or target
  // Returns relation "Unbound"
  MATCH (relation:ModelRelation)
  WHERE NOT (relation)-[:STARTS_AT]-&gt;() AND NOT (relation)-[:ENDS_AT]-&gt;()
  MATCH (allCategories:ModelCategory)
  RETURN relation, allCategories as target
  </code></pre>
  
  <p><strong>Question</strong></p>
  
  <p><strong>What is the best way to combine the four queries?</strong> <br/>
  The most simple solution is to add UNION between the statements. <br/>
  Maybe it's a good idea to get all nodes of the labels ModelRelation and ModelCategory first and execute further queries on sub-graphs?</p>
  
  <p><strong>Update</strong></p>
  
  <p>A better solution is to disginguish between relations with or without specified targets. (Resulting in one category or all categories.) One UNION is still necessary and the first part of both subqueries is the same.</p>
  
  <pre><code>// Relations which start at selected category or have no specified start
  MATCH (relation:ModelRelation)
  WHERE (relation)-[:STARTS_AT]-&gt;(:ModelCategory{title:"Cat"}) OR
        NOT (relation)-[:STARTS_AT]-&gt;()
  
  // Relations with specified targets
  Match (relation)-[ENDS_AT]-&gt;(target) 
  RETURN relation, target
  
  UNION
  
  // Relations which start at selected category or have no specified start
  MATCH (relation:ModelRelation)
  WHERE (relation)-[:STARTS_AT]-&gt;(:ModelCategory{title:"Cat"}) OR
        NOT (relation)-[:STARTS_AT]-&gt;()
  
  // Relations without specified targets
  MATCH (relation)
  WHERE NOT (relation)-[:ENDS_AT]-&gt;()
  MATCH (allCategories:ModelCategory)
  RETURN relation, allCategories as target
  </code></pre>