You have created the PLACED relationship between Customer and Order. You now have the data available to start querying the graph.
Counting customer orders
Write a query to find how many orders customer ANTON has placed:
cypher
Count orders for ANTON
MATCH (c:Customer {id: 'ANTON'})-[:PLACED]->(o:Order) // (1)
RETURN c.name, count(o) AS orderCount // (2)
Match pattern - Find ANTON and traverse to orders
Count aggregation - Count how many orders are connected
Click Run to see the result.
Try experimenting:
Change 'ANTON' to 'ALFKI' to see a different customer
Remove the WHERE to count orders for ALL customers: MATCH (c:Customer)-[:PLACED]→(o:Order) RETURN c.name, count(o) ORDER BY count(o) DESC LIMIT 10;
Finding customers with many orders
Find customers who have placed more than 10 orders:
cypher
Active customers (10+ orders)
MATCH (c:Customer) // (1)
WITH c, COUNT {
(c)-[:PLACED]->(o:Order)
} AS orderCount // (2)
WHERE orderCount > 10 // (3)
RETURN c.name, orderCount // (4)
ORDER BY orderCount DESC // (5)
Match pattern - Connect customers to their orders
Aggregate with WITH - The COUNT subquery finds the number of relationships
Filter aggregation - Only keep customers with more than 10 orders
Return results - Show company name and order count
Sort - Highest order counts first
Click Run to see your most active customers.
Querying order date ranges
Find the date range of orders for a specific customer:
cypher
Order history for ALFKI
MATCH (c:Customer {id: 'ALFKI'})
-[:PLACED]->(o:Order) // (1)
RETURN c.name, // (2)
min(o.date) AS firstOrder, // (3)
max(o.date) AS lastOrder, // (4)
count(o) AS totalOrders // (5)
Match pattern - Find customer and their orders
Customer name - Return the company name
Earliest order - Use min() to find first order date
Latest order - Use max() to find most recent order
Total count - How many orders in this time range
Click Run to see ALFKI’s ordering history.
Grouping orders by country
Find how many orders were shipped to each country:
cypher
Orders by ship country
MATCH (c:Customer)
-[:PLACED]->(o:Order) // (1)
RETURN o.shipCountry, // (2)
count(o) AS orderCount // (3)
ORDER BY orderCount DESC // (4)
LIMIT 10 // (5)
Match pattern - Connect customers to orders
Group by country - Implicitly groups by shipCountry
Count orders - Aggregate per country
Sort descending - Highest counts first
Limit - Top 10 countries
Click Run to see which countries receive the most orders.
Finding customers without orders
Find customers who haven’t placed any orders yet:
cypher
Customers with no orders
MATCH (c:Customer) // (1)
WHERE NOT (c)-[:PLACED]->(:Order) // (2)
RETURN c.name, c.country // (3)
Match all customers - Find every Customer node
Negative pattern - Filter to only customers WITHOUT PLACED relationships
Return customer info - Show who they are
Click Run to find customers who need outreach!
Hint
The WHERE NOT pattern here accesses the data store directly to find a count of the number of PLACED relationships, which is fast and efficient.
You’ll use negative patterns (WHERE NOT) in the recommendation query to exclude products you’ve already bought.
Summary
In this lesson, you practiced relationship traversal queries:
Basic traversals - Follow PLACED relationships from Customer to Order
Aggregation - Count orders per customer with count()
Date functions - min() and max() for date ranges
Grouping - Implicit grouping by returned properties
Negative patterns - Find customers without orders using the WHERE NOT clause
Building blocks - These patterns are foundations for the recommendation query
In the next module, you will add the critical Order→Product connection, completing the path needed for recommendations.