Supply Chain Knowledge Graph

Neo4j Demo Database - Setup & Exploration Guide

25
Products
8
Suppliers
7
Origins
10
Users

🚀 Setup Instructions

1

Go to Neo4j Aura (Free Tier)

Visit neo4j.com/cloud/aura-free and create a free instance

2

Open Neo4j Browser

Click "Open with Neo4j Browser" from your Aura console

3

Load the Demo Data

Copy the contents of supply-chain-demo.cypher and paste into the Neo4j Browser query editor, then run (Ctrl+Enter)

4

Explore!

Use the queries below to explore the graph visually

📊 Schema Overview

Node Types

  • Origin (7) - Countries where goods are made
  • Supplier (8) - Vendors supplying products
  • Product (25) - Kitchen products (SKUs)
  • Category (14) - Product taxonomy (L1/L2)
  • Warehouse (2) - Fulfillment centers
  • Store (3) - Retail locations
  • Channel (2) - Sales channels
  • User (10) - Customers

Relationship Types

  • LOCATED_IN Supplier → Origin
  • SUPPLIES Supplier → Product
  • BELONGS_TO Product → Category
  • PARENT_OF Category → Category
  • STOCKED_AT Product → Warehouse
  • FULFILLS Warehouse → Channel
  • STOCKED_FROM Store → Warehouse
  • VIEWED User → Product
  • PURCHASED User → Product
  • SUBSTITUTE_FOR Product → Product
  • COMPLEMENTARY_TO Product → Product

🔍 Demo Queries

Click any query to copy it, then paste into Neo4j Browser

Query 1: Vietnam Supply Chain Risk

"What products are at risk if Vietnam supply is disrupted?"

MATCH (o:Origin {countryCode: 'VN'})<-[:LOCATED_IN]-(s:Supplier)-[sup:SUPPLIES]->(p:Product)-[inv:STOCKED_AT]->(w:Warehouse)
RETURN o.countryName as Origin, s.name as Supplier, p.name as Product, p.sku as SKU,
       inv.daysCover as DaysCover, inv.quantityAvailable as Stock,
       CASE WHEN inv.daysCover < 7 THEN 'CRITICAL' 
            WHEN inv.daysCover < 14 THEN 'AT_RISK' 
            ELSE 'OK' END as RiskLevel
ORDER BY inv.daysCover ASC
Query 2: Supplier Concentration Risk

"Which suppliers have the most revenue exposure?"

MATCH (s:Supplier)-[sup:SUPPLIES {isPrimary: true}]->(p:Product)
WITH s, COUNT(p) as productCount, SUM(p.annualRevenue) as totalRevenue
MATCH (s)-[:LOCATED_IN]->(o:Origin)
RETURN s.name as Supplier, o.countryName as Origin, productCount, totalRevenue,
       s.onTimeRate as OnTimeRate
ORDER BY totalRevenue DESC
Query 3: Low Stock Alert

"What products need reordering based on days cover vs lead time?"

MATCH (p:Product)-[inv:STOCKED_AT]->(w:Warehouse)
WHERE inv.daysCover < 14
MATCH (p)<-[sup:SUPPLIES {isPrimary: true}]-(s:Supplier)
RETURN p.sku as SKU, p.name as Product, w.name as Warehouse,
       inv.quantityAvailable as Stock, inv.daysCover as DaysCover,
       s.name as Supplier, sup.leadTimeDays as LeadTime,
       CASE WHEN inv.daysCover < sup.leadTimeDays THEN 'ORDER NOW' ELSE 'MONITOR' END as Action
ORDER BY inv.daysCover ASC
Query 4: Product Substitutes for Stockout

"If premium chef knife stocks out, what alternatives exist?"

MATCH (p:Product {sku: 'KN-4521'})-[sub:SUBSTITUTE_FOR]->(alt:Product)-[inv:STOCKED_AT]->(w:Warehouse)
WHERE inv.quantityAvailable > 0
RETURN p.name as OutOfStock, alt.sku as AlternativeSKU, alt.name as Alternative,
       sub.similarityScore as Similarity, sub.direction as Type,
       alt.price as Price, inv.quantityAvailable as InStock
ORDER BY sub.similarityScore DESC
Query 5: Customer Segment Analysis

"What do Premium Aesthetic Enthusiasts buy?"

MATCH (u:User {segmentName: 'Premium Aesthetic Enthusiasts'})-[pur:PURCHASED]->(p:Product)-[:BELONGS_TO]->(c:Category)
WITH c.name as Category, SUM(pur.totalRevenue) as Revenue, COUNT(DISTINCT u) as Customers
RETURN Category, Revenue, Customers
ORDER BY Revenue DESC
Query 6: Full Supply Chain Path (Visual) Best for visualization

"Trace complete supply chain for Carbon Steel Wok - Origin to Channel"

MATCH path = (o:Origin)<-[:LOCATED_IN]-(s:Supplier)-[:SUPPLIES]->(p:Product {sku: 'WK-8834'})-[:STOCKED_AT]->(w:Warehouse)-[:FULFILLS]->(ch:Channel)
RETURN path
Query 7: Category Performance by Origin

"Which origins supply which categories?"

MATCH (o:Origin)<-[:LOCATED_IN]-(s:Supplier)-[:SUPPLIES]->(p:Product)-[:BELONGS_TO]->(c:Category {level: 1})
WITH o.countryName as Origin, c.name as Category, SUM(p.annualRevenue) as Revenue
RETURN Origin, Category, Revenue
ORDER BY Origin, Revenue DESC
Query 8: Complementary Products

"What products are frequently bought with woks?"

MATCH (p:Product)-[:BELONGS_TO]->(c:Category {categoryId: 'cookware/woks'})
MATCH (p)-[comp:COMPLEMENTARY_TO]->(rec:Product)
RETURN p.name as Product, rec.name as Recommendation, comp.lift as Lift, comp.coPurchaseCount as TimesBoughtTogether
ORDER BY comp.lift DESC
Query 9: Entire Graph Overview (Visual) Start here!

"See the entire graph structure - best for presenting the data model"

MATCH (n)
OPTIONAL MATCH (n)-[r]->(m)
RETURN n, r, m
LIMIT 200
Query 10: User Journey Visualization Great for demo

"Show a premium customer's complete purchase history and supply chain"

MATCH (u:User {userId: 'USR-007'})-[rel:PURCHASED|VIEWED]->(p:Product)
OPTIONAL MATCH (p)<-[:SUPPLIES]-(s:Supplier)-[:LOCATED_IN]->(o:Origin)
OPTIONAL MATCH (p)-[:BELONGS_TO]->(c:Category)
RETURN u, rel, p, s, o, c
Query 11: Products with Backup Suppliers

"Which products have backup suppliers for risk mitigation?"

MATCH (p:Product)<-[primary:SUPPLIES {isPrimary: true}]-(ps:Supplier)
OPTIONAL MATCH (p)<-[backup:SUPPLIES {isPrimary: false}]-(bs:Supplier)
WITH p, ps, primary, COLLECT({supplier: bs.name, leadTime: backup.leadTimeDays, cost: backup.unitCost}) as backups
WHERE SIZE(backups) > 0 AND backups[0].supplier IS NOT NULL
RETURN p.sku as SKU, p.name as Product, 
       ps.name as PrimarySupplier, primary.leadTimeDays as PrimaryLeadTime,
       backups as BackupSuppliers
ORDER BY p.sku

💡 Tips for Presenting

Supply Chain Knowledge Graph Demo • Built for Neo4j Aura