Opens your running SynapCores (Product co-purchase, customers also bought will be staged for a preview — nothing runs until you click Run). No instance yet? Install free in ~30s.
Share
Objective
Replicate Amazon's "customers who bought this also bought" widget directly in SQL. With Cypher,
the bipartite Customer→Order→Product graph collapses into a single pattern that finds co-purchased
items and ranks them by support — useful for upsell, cross-sell, and merchandising rules.
Step 2: Customers who bought espresso beans also bought…
// Co-occurrence: walk Order→Product to Order→other Product through the same order.
MATCH (target:Product {sku: "ESP-01"})<-[:CONTAINS]-(o:Order)-[:CONTAINS]->(other:Product)
WHERE other <> target
RETURN other.sku AS sku,
other.name AS also_bought,
count(o) AS times_co_purchased
ORDER BY times_co_purchased DESC, sku;
What's happening
The bipartite hop (target)<-(o)->(other) finds every product sharing an order with the target.
count(o) produces market-basket support directly — no pivoting, no temp tables.
Cypher's pattern is symmetric: swap the SKU and you get a different recommender for free.
Adding more relationship types (e.g. :VIEWED, :WISHLISTED) extends the model without schema
migrations — graph databases shine when you keep adding signals over time.
In SQL this is a self-join on order_items plus aggregation; with millions of rows it gets slow,
while the graph version follows pointers and stays fast.
Try this next
MATCH (c:Customer)<-[:PLACED_BY]-(o:Order)-[:CONTAINS]->(p:Product)
RETURN c.name AS customer, sum(p.price) AS lifetime_value
ORDER BY lifetime_value DESC;
MATCH (p:Product)<-[:CONTAINS]-(o:Order)
RETURN p.name AS product, count(o) AS orders
ORDER BY orders DESC LIMIT 5;
MATCH (a:Product)<-[:CONTAINS]-(o:Order)-[:CONTAINS]->(b:Product)
WHERE a.sku < b.sku
RETURN a.name, b.name, count(o) AS support
ORDER BY support DESC LIMIT 10;