2

I am in need of get data of whether there is no relation exists between two labels and condition based data on one of labels. I found an answer following ::

MATCH (n:Label1) 
WHERE NOT (n)-[:REL_1]-(:Label2) 
OR (n)-[:REL_1]-(e:Label2 {id:1}) 
RETURN count(DISTINCT(n))

But What I need is like all of id>=5 data should come in result

If I perform a query like ::

MATCH (n:Label1) 
WHERE NOT (n)-[:REL_1]-(:Label2) 
OR (n)-[:REL_1]-(e:Label2) 
WHERE e.id >= 5 
RETURN count(DISTINCT(n))

It is producing error ::

Invalid input 'H': expected 'i/I' (line 1, column 94 (offset: 93)) 
chikku
  • 863
  • 1
  • 7
  • 19
  • Your last WHERE has a variable `e`, but that's not present anywhere else in your query. Was that meant to be `n`, or did you forget to add the `e` variable elsewhere in your query? – InverseFalcon Oct 21 '16 at 07:13

2 Answers2

3

[UPDATED]

A Cypher query cannot have 2 WHERE clauses in a row. In addition, you have not defined the e identifier.

This query should work (I assume you only want to count n if it does not have such a relationship OR if it has at least one in which e.id is at least 5):

MATCH (n:Label1)
OPTIONAL MATCH (n)-[:REL_1]-(e:Label2)
WITH n, e
WHERE e IS NULL OR e.id >= 5
RETURN count(DISTINCT n);
cybersam
  • 63,203
  • 6
  • 53
  • 76
  • count is mismatching I'm having empty relations count 1050 and exist relations count 507 ; According to your query If I remove e.id >= 5 It is not giving exact count(1050) it is giving count of 1557 which is total count. What to do? – chikku Oct 21 '16 at 07:34
  • 1
    The WHERE applies only to the OPTIONAL MATCH, which isn't actually what you want, as it does nothing to filter on results from your first match. Try adding `WITH n, e` between your OPTIONAL MATCH and the WHERE. – InverseFalcon Oct 21 '16 at 07:44
  • Nice catch. Updated my answer. – cybersam Oct 21 '16 at 14:40
  • This assumes that if `(n)` connects to two `(e)` nodes, it should still be counted as long as one of them meets the condition. If you want to exclude any `(n)` that touches a bad `(e)` node, this approach won't work. – Tore Eschliman Oct 21 '16 at 18:26
0

You can nest WHERE filters, you just have to give up syntactic sugar to do it.

MATCH (n:Label1)
WHERE ALL(p IN (n) - [:REL_1] - (:Label2) WHERE LAST(NODES(p))['id'] >= 5)
RETURN COUNT(n)

You reconstruct any match-filter construct you can dream of with the ANY, ALL, NONE toolset, which allow you to apply filters internally as well and nest the iterable component (between IN and `WHERE) to multiple depths.

Tore Eschliman
  • 2,477
  • 10
  • 16