Search code examples
neo4jcypher

How to make two Cypher optional matches not multiply results?


OPTIONAL MATCH (:User)-[l:LIKED]->(:User {username: $username})
OPTIONAL MATCH (:User)-[d:DISLIKED]->(:User {username: $username})
RETURN count(l),count(d)

I have this Cypher query to return the count of 2 types of relationships. Currently there are 7 :LIKED edges and 5 :DISLIKED edges running into the given username, but when I run this I get both counts as 35. How can I change it to not be multiplied?


Solution

  • If the start node of every LIKED and DISLIKED relationship is always a User, then we can use a path pattern that leaves the start node unspecific. In this case, the most efficient way to get the counts is as follows (since it causes the Cypher planner to count relationships using the getDegree operation, which does not need to hit the DB):

    OPTIONAL MATCH (u:User {username: $username})
    RETURN
      SIZE([()-[:LIKED]->(u)|1]) AS count_l,
      SIZE([()-[:DISLIKED]->(u)|1]) AS count_d
    

    This answer to another question provides more details.