1
votes

Suppose I have the following graph

CREATE 
(n1:Person {name: "David Wallace", role: "CFO", dept: "management"}),
(n2:Person {name: "Ryan Howard", role: "VP, North East Region", dept: "management"}),
(n3:Person {name: "Toby Flenderson", role: "HR Rep.", dept: "HR"}),
(n4:Person {name: "Michael Scott", role: "Regional Manager", dept: "management"}),
(n5:Person {name: "Todd Pecker", role: "Travel Sales Rep.", dept: "Sales"}),
(n6:Person {name: "Angela Martin", role: "Senior Accountant", dept: ["Accounting", "Party Planning Committee"]}),
(n7:Person {name: "Dwight Schrute", role: ["Sales", "Assistant to the Regional Manager"], dept: "Sales"}),
(n8:Person {name: "Jim Halpert", role: ["Sales", "Assistant Regional Manager"], dept: "Sales"}),
(n9:Person {name: "Pam Beesley", role: "Receptionist", dept: "Reception"}),
(n10:Person {name: "Creed Barton", role: "Quality Assurance Rep.", dept: "Quality Control"}),
(n11:Person {name: "Darryl Philbin", role: "Warehouse Foreman", dept: "Warehouse"}),
(n12:Person {name: "Kevin Malone", role: "Accountant", dept: "Accounting"}),
(n13:Person {name: "Oscar Martinez", role: "Accountant", dept: "Accounting"}),
(n14:Person {name: "Meredith Palmer", role: "Supplier Relations", dept: "Supplier Relations"}),
(n15:Person {name: "Kelly Kapoor", role: "Customer Service Rep.", dept: "Customer Service"}),
(n16:Person {name: "Jerry DiCanio", dept: "Warehouse"}),
(n17:Person {name: "Madge Madsen", dept: "Warehouse"}),
(n18:Person {name: "Lonnie Collins", dept: "Warehouse"}),
(n19:Person {name: "Andy Bernard", role: "Regional Director in Sales", dept: "Sales"}),
(n20:Person {name: "Phyllis Lapin", role: "Sales", dept: "Sales"}),
(n21:Person {name: "Stanley Hudson", role: "Sales", dept: "Sales"}),
(n1)-[:manages]->(n2),
(n2)-[:manages]->(n3),
(n2)-[:manages]->(n4),
(n2)-[:manages]->(n5),
(n4)-[:manages]->(n6),
(n4)-[:manages]->(n7),
(n4)-[:manages]->(n8),
(n4)-[:manages]->(n9),
(n4)-[:manages]->(n10),
(n4)-[:manages]->(n11),
(n4)-[:manages]->(n14),
(n4)-[:manages]->(n15),
(n6)-[:manages]->(n12),
(n6)-[:manages]->(n13),
(n8)-[:manages]->(n19),
(n11)-[:manages]->(n16),
(n11)-[:manages]->(n17),
(n11)-[:manages]->(n18),
(n19)-[:manages]->(n20),
(n19)-[:manages]->(n21);

and I have the following query

Does Michael directly manage more employees than Jim Halpert?

I come up with the following Cypher query

MATCH (p:Person)<-[:manages]-(n:Person)
WHERE n.name = "Michael Scott"
MATCH (q:Person)<-[:manages]-(m:Person)
WHERE m.name = "Jim Halpert"
RETURN count(p) > count(q)

The query returns false. I checked both count(p) and count(q) are 8. I was wondering why is this? Also, what's the scope of MATCH statement meaning will p and q bind to the different variables (i.e., variable only visible in the MATCH statement scope; I can re-use the same variable for different MATCH statement)?

Thanks!

2

2 Answers

2
votes

The two matches in your query are forming a catrtesian product, returning one p for each q (1 x 8). If you substitute Darryl Philbin for Jim Halpert you will appear to get 24 counts for each p and q (3 x 8).

You will see what's happening more clearly if you run:

MATCH (p:Person)<-[:manages]-(n:Person)
WHERE n.name = "Michael Scott"
MATCH (q:Person)<-[:manages]-(m:Person)
WHERE m.name = "Jim Halpert"
RETURN p.name, q.name

As Lukasmp3 says, introducing a WITH breaks the query into two distinct parts and stops the catresian product from forming, you'll then get the expected answer.

1
votes

A good approach when chaining more MATCH clauses is to use WITH statement that separates query parts explicitly, allowing you to declare which variables to carry over to the next part.

In your case:

MATCH (p:Person)<-[:manages]-(n:Person)
WHERE n.name = "Michael Scott"
WITH count(p) AS countP
MATCH (q:Person)<-[:manages]-(m:Person)
WHERE m.name = "Jim Halpert"
RETURN countP > count(q)