Supply Chain & BOM Analysis¶
Supply chains are deeply nested graphs (Part A -> Part B -> Part C). Uni's specialized support for recursive traversals and document storage makes it an excellent fit for Bill of Materials (BOM) management and impact analysis.
Why Uni for Supply Chain?¶
| Challenge | Traditional Approach | Uni Approach |
|---|---|---|
| Recursive Depth | SQL WITH RECURSIVE is slow and hard to optimize. |
Vectorized Recursion: MATCH (n)-[:PART_OF*]->(m) is optimized for deep paths. |
| Variable Data | Parts have widely varying specs (resistors vs. CPUs). Relational schemas explode. | Document Mode: Store distinct part specs as JSON in the same Part table. |
| Analytics | Hard to aggregage cost/weight up the tree. | Aggregation Pushdown: Fast summation over traversal paths. |
Scenario: Product Impact Analysis¶
A supplier notifies you that "Part X" has a defect. You need to find: 1. All finished products that contain Part X (recursively). 2. The total revenue at risk.
1. Schema Definition¶
We enable Document Mode for Part to store varied technical specifications.
schema.json
{
"labels": {
"Part": {
"id": 1,
"is_document": true // Allows storing arbitrary JSON in _doc
},
"Supplier": { "id": 2 },
"Product": { "id": 3 }
},
"edge_types": {
"ASSEMBLED_FROM": { "id": 1, "src_labels": ["Part", "Product"], "dst_labels": ["Part"] },
"SUPPLIED_BY": { "id": 2, "src_labels": ["Part"], "dst_labels": ["Supplier"] }
},
"properties": {
"Part": {
"sku": { "type": "String", "nullable": false },
"cost": { "type": "Float64", "nullable": false }
},
"Product": {
"name": { "type": "String", "nullable": false },
"price": { "type": "Float64", "nullable": false }
}
},
"indexes": [
{
"type": "Scalar",
"name": "part_sku",
"label": "Part",
"properties": ["sku"],
"index_type": "Hash"
},
{
"type": "Scalar",
"name": "json_spec_voltage",
"label": "Part",
"properties": ["$.specs.voltage"], // JSON Path Indexing (Planned feature)
"index_type": "BTree"
}
]
}
2. Ingestion (With Documents)¶
When inserting parts, we put fixed fields in properties and variable fields in _doc.
// Rust Example
writer.insert_vertex(vid, json!({
"sku": "RES-10K",
"cost": 0.05,
"_doc": {
"type": "resistor",
"specs": { "resistance": "10k", "tolerance": "5%" },
"compliance": ["RoHS"]
}
})).await?;
3. Query: BOM Explosion¶
Find all products affected by the defective part.
// Start at the defective part
MATCH (defective:Part {sku: 'RES-10K'})
// Traverse UP the assembly tree (incoming ASSEMBLED_FROM edges)
// Variable length path: *1..20 levels deep
MATCH (product:Product)-[:ASSEMBLED_FROM*1..20]->(defective)
// Return unique affected products and their price
RETURN DISTINCT
product.name,
product.price
ORDER BY product.price DESC
4. Query: Cost Rollup¶
Calculate the total cost of a product by summing the cost of all its constituent parts.
MATCH (p:Product {name: 'Smartphone X'})
MATCH (p)-[:ASSEMBLED_FROM*]->(part:Part)
RETURN p.name, SUM(part.cost) AS total_bom_cost
Key Advantages¶
- Deep Traversal Speed: Uni's adjacency cache ensures that each hop is a simple memory lookup, not a disk seek. BOM explosions that take seconds in SQL take milliseconds in Uni.
- Schema Flexibility: You can store resistors, capacitors, screens, and batteries in the same
Partdataset without a sparse column mess. - Vector Potential: You could even add embeddings to parts (e.g., image of the component) to find visual duplicates in your inventory.