Search code examples
memgraphdb

How can I count 1:N:1 and N:1:N manners?


I'd like to do a count in the manner of 1:N:1 and N:1:N.

Here is my query, but it is not doing exactly what I want:

Match 
  (V1)-[e1]->(v2)->[e2]->(v3)
With
  Count(distinct(v1.property)) as cntleft , count(distinct(v3.property)) as cntright
Where
 cntleft=1 and cntright=1
Return 
  Count(v2)

Solution

  • Here is a working query in Memgraph:

    MATCH (v1)-[e1]->(v2)-[e2]->(v3)
    WITH COUNT(DISTINCT v1) AS left, COUNT(DISTINCT v3) as right, v1, v2, v3
    WHERE left = 1 AND right = 1
    WITH collect(v2) AS n, v1, v3
    RETURN COUNT(*);
    

    First, we have to be careful with relationships (->). This kind of construct is not supported:

    (v2)->[e2]->(v3)
    

    because it is enough to put (v2)-[e2]->(v3).

    Then, as you can see in the above query, the usage of DISTINCT is without the parenthesis, and you don't have to use a certain property to count what you wanted. It is enough to count the distinct nodes.

    The other this you have to do is not to forget to pipe v1, v2, and v3, since we need them later on. I think this part with left and right = 1 is fine, and in the end, I collected these kind of v2's to count all 1:N:1, instead of 1:v2:1, 1:v2:1,..as a result. To see the relationships you got, you can run:

    MATCH (v1)-[e1]->(v2)-[e2]->(v3)
    WITH COUNT(DISTINCT v1) AS left, COUNT(DISTINCT v3) as right, v1, v2, v3
    WHERE left = 1 AND right = 1
    RETURN v1, collect(v2) AS n, v3;
    

    Similarly, for N:1:N, I would run:

    MATCH (v1)-[e1]->(v2)-[e2]->(v3)
    WITH COUNT(DISTINCT v2) AS middle, v1, v2, v3
    WHERE middle = 1
    WITH collect(v1) AS n1, v2, collect(v3) AS n2
    RETURN COUNT(*);
    

    That is, to discover the nodes:

    MATCH (v1)-[e1]->(v2)-[e2]->(v3)
    WITH COUNT(DISTINCT v2) AS middle, v1, v2, v3
    WHERE middle = 1
    RETURN collect(v1), v2, collect(v3);