cookbook/ Supply Chain Patterns
Last Updated: October 20, 2018Graph patterns for logistics, inventory, and dependency analysis.
Supply Chain Cookbook
Optimize logistics and track dependencies with these graph-native queries.
1. Inventory & Tracking
Bill of Materials (BOM) Explosion
gsqlterminal// Get all sub-components and quantities for a final product CREATE QUERY explode_bom(VERTEX<Product> p) FOR GRAPH SupplyChain { SumAccum<INT> @total_qty; Start = {p}; Start = SELECT s FROM Start:s ACCUM s.@total_qty = 1; WHILE Start.size() > 0 DO Start = SELECT t FROM Start:s -(HAS_PART:e)-> Product:t ACCUM t.@total_qty += s.@total_qty * e.quantity; END; PRINT Product[Product.name, Product.@total_qty]; }
Critical Path Dependency
gsqlterminal// Find the longest lead time path in a multi-stage production CREATE QUERY critical_production_path(VERTEX<Product> p) FOR GRAPH SupplyChain { MaxAccum<INT> @max_lead_time; Start = {p}; WHILE Start.size() > 0 DO Start = SELECT t FROM Start:s -(DEPENDS_ON:e)-> Product:t ACCUM t.@max_lead_time += s.@max_lead_time + t.lead_time; END; PRINT Product[Product.name, Product.@max_lead_time]; }
2. Logistics & Routing
Shortest Delivery Path (Dijkstra-style)
gsqlterminal// Find the fastest route between two warehouses CREATE QUERY fastest_route(VERTEX<Warehouse> start_node, VERTEX<Warehouse> end_node) FOR GRAPH SupplyChain { MinAccum<INT> @min_dist = 999999; ListAccum<VERTEX<Warehouse>> @path; Start = {start_node}; Start = SELECT s FROM Start:s ACCUM s.@min_dist = 0; WHILE Start.size() > 0 DO Start = SELECT t FROM Start:s -(ROAD:e)-> Warehouse:t WHERE s.@min_dist + e.travel_time < t.@min_dist ACCUM t.@min_dist = s.@min_dist + e.travel_time, t.@path = s.@path + [s]; END; EndNode = {end_node}; PRINT EndNode[EndNode.@min_dist, EndNode.@path]; }
3. Risk & Impact Analysis
Factory Shutdown Impact
gsqlterminal// List all final products affected if a specific factory shuts down CREATE QUERY factory_impact(VERTEX<Factory> f) FOR GRAPH SupplyChain { OrAccum @affected = false; Start = {f}; WHILE Start.size() > 0 DO Start = SELECT t FROM Start:s -((REVERSE_PRODUCED_BY|REVERSE_HAS_PART):e)- :t WHERE t.@affected == false ACCUM t.@affected = true; END; Products = {Product.*}; Result = SELECT s FROM Products:s WHERE s.@affected == true; PRINT Result.size() AS affected_count, Result; }
4. Quality Control
Batch Recall (Lineage)
gsqlterminal// Find all customers who received products from a tainted batch of raw material CREATE QUERY batch_recall(VERTEX<Batch> tainted_batch) FOR GRAPH SupplyChain { SetAccum<VERTEX<Customer>> @@affected_customers; Start = {tainted_batch}; // Trace forward from batch -> product -> order -> customer WHILE Start.size() > 0 DO Start = SELECT t FROM Start:s -(USED_IN|SOLD_AS|PURCHASED_BY:e)-> :t; IF Start.type == "Customer" THEN Result = SELECT s FROM Start:s ACCUM @@affected_customers += s; END; END; PRINT @@affected_customers; }
[!TIP] Use Reverse Edges in your schema to allow the
factory_impactquery to traverse "up" the supply chain from raw components to finished goods.