供应链(制药)演示
简介
供应链是世界上最复杂和受严格监管的系统之一。它们涵盖了原材料供应商、制造商、物流供应商和分销商——所有这些都紧密交织,并依赖于可靠、可追溯的流。传统系统常常难以提供管理中断、质量问题或假冒风险所需的可见性。线性报告和孤立的数据使得追踪产品血统或实时响应变得困难。
借助 Neo4j,您可以利用原生图数据库和灵活的图模型,绘制产品从原材料到成品的完整生命周期,并获得有关供应路径、依赖关系和漏洞的可操作洞察。
本设置指南展示了 Neo4j 如何使用图原生方法建模和分析制药供应链。您将探索关键的供应链维度,例如:
-
供应商和分销商关系
-
批次追溯和溯源
-
需求回溯传播
-
瓶颈和风险识别
-
设备利用和优化
您还将学习如何设置 Neo4j AuraDB 实例、导入样本数据集、探索供应链图模型,以及运行查询以揭示供应网络中的结构、流和风险。
先决条件
要运行这些示例,您需要以下内容:
|
遵循此演示中的说明将替换您实例中的数据,因此请务必备份您不想丢失的任何数据;或者,您可以创建一个全新的实例来使用(推荐)。 |
-
(可选,但强烈推荐)一个可以运行 Jupyter Notebooks 的 Python 安装。本演示的所有查询都在 Notebooks 中提供;您也可以将查询复制粘贴到 Aura 控制台的“查询”或“探索”工具中。
-
(可选,但推荐)git 客户端软件以下载演示资产。
-
可选:本地安装 Cypher Workbench,如果您想尝试编辑数据模型的工具。
设置数据库
1. 确保您的 Neo4j AuraDB 实例正在运行。如果您是 AuraDB 新用户,请在 https://concole.neo4j.io 创建帐户,然后点击“创建实例”。
|
请务必保存您的凭据——您稍后需要它们来连接到您的数据库。请等到实例状态显示“运行中”再进行下一步。 |
2. 从 GitHub 仓库克隆 git 仓库。您可以使用以下命令完成:
git clone https://github.com/neo4j-product-examples/demo-supply_chain.git
或者,您可以使用 GitHub 仓库上的“下载 ZIP”选项下载副本。
3. 使用 .backup 文件将数据加载到数据库。在 Aura 控制台中,使用“...三点”菜单,选择“备份与恢复”。
|
使用“浏览”按钮或拖放来查找 |
4. 审阅有关替换实例数据的警告,并在准备就绪后继续。
5. 当您的数据库实例达到“运行中”状态时,您就可以运行示例了。
6. 确保您已安装以下 Python 库:
-
python-dotenv -
neo4j -
neo4j-tools -
neo4j-viz
您可以使用以下任一选项安装它们:
pip install python-dotenv neo4j neo4j-tools neo4j-viz
pip install -r requirements.txt
python -m venv env
source env/bin/activate # On Windows: env\Scripts\activate
pip install -r requirements.txt
7. 在您的 git 工作副本的 src 目录中,复制 sc_p.env.template 文件,将其命名为“sc_p.env”,并编辑该文件以包含您的 AuraDB 实例的 URI 和密码。
理解图数据模型
该图模型通过连接关键实体及其关系,绘制了药品的完整生命周期。它捕获了分析生产、追溯和分销所需的数据结构和流,提供了一个互联的端到端视图。
/* Run this query to view the schema or graph model of the dataset */
CALL db.schema.visualization();
关键实体
-
供应商:提供原材料和活性成分。
-
原材料 (RM):初始配方所需的基本物质。
-
活性药物成分 (APIs):核心生物活性成分。
-
产品阶段:散装 → DP(药品)→ 成品药。
-
批次:在整个生产过程中跟踪的材料或产品单位。
-
设备:每个生产步骤中涉及的机器和生产线。
-
分销商:负责将成品药交付给药房或医疗服务提供商的实体。
依赖链
此视图展示了给定药品 SKU 的完整依赖链。查询追踪产品如何流经供应链的每个阶段——从原材料供应商开始,经过原材料 (RM) 和活性药物成分 (APIs),进入药品生产的各个阶段(散装 → DP → 成品),最后到达分销商。
通过将供应链可视化为图,您可以:
-
追溯任何产品的血统:识别构成成品药的每一个输入——供应商、材料、中间产品。
-
揭示相互依赖:了解哪些原材料或供应商被多个产品线使用。
-
检测漏洞:发现单点故障,例如过度依赖特定供应商或生产瓶颈。
-
探索上游和下游:查看双向影响——例如,供应商延迟如何影响下游分销,或者哪些供应商参与了质量控制失败的批次。
这种基于图的方法实现了实时、直观的探索,而传统的关系型连接难以或无法复制。
通过关注特定的 productSKU,此查询有助于供应链团队精确识别该产品制造和分销生命周期中涉及的材料流和关系。
/*
Finds the full supply chain path for a specific product SKU —
from supplier to distributor, across all production stages.
*/
MATCH path =
(sup:Suppliers) // Supplier
-[:SUPPLIES_RM]->
(rm:RM) // Raw Material
-[:PRODUCT_FLOW*]->
(prod:Product) // Product stages (API, DP, FG)
-[:DISTRIBUTED_BY]->
(dist:Distributor) // Distributor
WHERE prod.productSKU = '7e882292-ae98-45eb-8119-596b5d8b73e1' // Filter by SKU
RETURN
nodes(path) AS nodes,
relationships(path) AS relationships
理解原材料需求
识别供应商冗余度有限的原材料
此查询找出仅由一个供应商提供的原材料 (RM),突出了因缺乏供应商冗余而导致的潜在瓶颈或风险。
它的工作原理是:- 计算每个原材料连接的供应商数量 - 筛选只包含 supplierCount = 1 的原材料
这种模式有助于利益相关者主动检测采购流程中的单点故障——这在药品生产中尤为重要,因为单一原材料的延迟或短缺可能扰乱整个产品流。
|
展示了一种侧重于 |
/*
Finds Raw Materials (RMs) with only one supplier —
potential risk points due to lack of redundancy.
*/
MATCH (rm:RM)<-[:SUPPLIES_RM]-(sup:Suppliers) // Match each RM to its suppliers
WITH rm, COUNT(sup) AS supplierCount // Count number of suppliers per RM
WHERE supplierCount = 1 // Keep only RMs with a single supplier
RETURN
rm.productSKU AS rawMaterialSKU,
rm.globalBrand AS rawMaterialName,
supplierCount // Should always be 1 in this case
ORDER BY supplierCount
映射终端需求以推动原材料规划
此查询将下游分销商需求映射到特定产品配置,并作为反向工程原材料需求的起点。通过分析目标市场(例如欧盟)对特定药物(如 Calciiarottecarin(50 毫克胶囊,g2))的需求,团队可以追溯上游依赖关系——包括 API 和原材料——以指导准确的采购和生产计划。
MATCH p = (dist:Distributor WHERE dist.market = "EU")
<-[db:DISTRIBUTED_BY]-
(prod:Product
WHERE prod.globalBrand = "Calciiarottecarin"
AND prod.strength = "50mg"
AND prod.form = "Caplet"
AND prod.generation = "g2")
<-[pf:PRODUCT_FLOW]-(:Product)
// Trace demand for a specific drug from a specific market
RETURN prod.globalBrand AS globalBrand,
dist.market AS market,
dist.location AS distributor,
prod.form AS form,
prod.strength AS strength,
prod.package AS package,
db.demandQty AS demandQty,
prod.productSKU AS productSKU
// Output key demand attributes used to drive raw material planning
ORDER BY demandQty DESC
供应链优化
识别整个供应链中的关键风险和低效率——例如共享资源 API、单一供应商瓶颈、来自分销商需求的材料要求以及冗余或循环物流路径。
查找在多种药品中使用的具有潜在供应风险的 APIs
此查询识别在多种药品中使用的活性药物成分 (APIs)。使用范围更广的 APIs 可能带来供应风险——中断可能同时影响多个产品,尤其当需求在产品线之间重叠时。为了突出更关键的情况,查询筛选了链接到超过 4 种不同药品的 APIs。
|
这种模式突出显示了 |
/*
Finds APIs used in more than 4 different Drug Products (DP),
indicating potential supply risk due to shared dependency.
*/
MATCH (api:API)-[:PRODUCT_FLOW]->(dp:DP) // Match API to its connected Drug Products
WITH api, COUNT(dp) AS productCount // Count how many DPs each API is used in
WHERE productCount > 4 // Focus on APIs used in multiple products
RETURN
api.productSKU AS apiSKU,
api.globalBrand AS apiName,
productCount // Number of associated Drug Products
ORDER BY productCount DESC
标记高影响且冗余度低的 APIs
此查询通过关注满足两个高风险条件的活性药物成分 (APIs) 来识别关键供应链漏洞:
-
它们被用于多种药品中,表明整个产品组合的高度依赖性。
-
它们仅由一个供应商提供,造成潜在的单点故障。
通过结合这些标准,查询突出了具有广泛产品影响和低采购冗余的 APIs——这是药品生产中的一个关键风险指标。
这一洞察有助于利益相关者主动标记瓶颈、加强采购策略并降低生产中断的风险。
|
展示了一种以 |
/*
Identifies APIs used in more than 4 Drug Products.
Flags those that are supplied by only one supplier — potential bottlenecks.
*/
MATCH (sup:Suppliers)-[:SUPPLIES_RM]->(rm:RM)
-[:PRODUCT_FLOW]->(api:API)
-[:PRODUCT_FLOW]->(dp:DP) // Trace path: Supplier → RM → API → Drug Product
WITH
api,
COUNT(dp) AS productCount, // How many DPs use this API
COLLECT(DISTINCT dp) AS dpList, // Optional: full list of DPs
COUNT(DISTINCT sup) AS supplierCount, // How many unique suppliers supply this API
COLLECT(DISTINCT sup.companyName) AS supplierList
WHERE productCount > 4 // Filter: API must be used in 4+ products
RETURN
api.productSKU AS apiSKU, api.globalBrand AS apiName,
productCount, supplierCount,supplierList,
CASE
WHEN supplierCount = 1
THEN 'Single Supplier Bottleneck!!' // Flag risky APIs
ELSE 'Multiple Suppliers Available'
END AS SupplierRisk
ORDER BY supplierCount ASC // Show most constrained APIs first
分销商需求如何反向流向原材料需求?
此查询回答了一个关键的供应链问题:“满足分销商层面的需求需要多少原材料?”
它的工作原理是沿着供应链反向追溯需求——从分销商开始,一直到原材料及其供应商。
逐步分解
-
从分销商请求的特定产品 (
productSKU) 开始 -
捕获该分销商的需求数量
-
根据共享的产品属性(例如品牌、强度、形式、代次)找到用于制造该产品的原材料 (RM)
-
追溯从原材料到产品的最短路径(通过 API、散装、DP 等阶段)
-
识别每种原材料的供应商
-
计算所需的原材料数量,考虑每个步骤的转换率
|
使用 |
/*
Trace demand from a distributor back to raw material quantity requirements.
*/
MATCH (d:Distributor)<-[db:DISTRIBUTED_BY]-(prod:Product)
WHERE prod.productSKU = '9a6b431f-3a38-4b45-9451-fbf39b2e2fd0' // Start with a specific product
MATCH (api)<-[pf2:PRODUCT_FLOW]-(rm:RM)
WHERE pf2.globalBrand = prod.globalBrand
AND pf2.strength = prod.strength
AND pf2.form = prod.form
AND pf2.generation = prod.generation // Match equivalent raw materials by product attributes
WITH d, db.demandQty AS demandQty, db, prod, COLLECT(DISTINCT rm) AS RMList
UNWIND RMList AS curRM // Process each matching raw material
MATCH p = shortestPath((prod)<-[pf1:PRODUCT_FLOW*]-(curRM)) // Trace shortest path from RM to product
MATCH p3 = (myProd:Product)<-[pf:PRODUCT_FLOW]-(curRM)<-[:SUPPLIES_RM]-(sup:Suppliers)
WHERE pf.globalBrand = prod.globalBrand
AND pf.strength = prod.strength
AND pf.form = prod.form
AND pf.generation = prod.generation
AND pf.market = d.market // Match supplier relationships in the same market
RETURN
sup.companyName AS supplierName,
curRM.productSKU AS rawMaterialSKU,
apoc.coll.disjunction(["Product"], labels(myProd))[0] AS usedBy, // Identify final product stage (API, DP, etc.)
demandQty,
REDUCE(rmQty = demandQty, rel IN relationships(p) |
TOINTEGER(ROUND(rmQty / (COALESCE(rel.conversionRatio, 1.0)), 0))
) AS rawMaterialQty
ORDER BY usedBy, supplierName, rawMaterialSKU
检测成品 → 分销流中的跨境或循环运输
此查询分析成品 (FG) 在供应链中的移动,以检测潜在的运输效率低下或物流异常。它追踪从成品药 (FG) 到分销 (DIST) 的产品流,并突出显示两个关键模式:
重要性
识别这些模式有助于供应链团队:- 降低不必要的运输成本 - 提高路线效率 - 减轻与过于复杂或非最优物流网络相关的风险
/*
Detects either Cross-Border or Cyclic shipment patterns
in Finished Goods (FG) to Distributor (DIST) product flows.
*/
MATCH (fg:FG:Product WHERE fg.globalBrand = "Calciiarottecarin") // Start with FG products for a specific brand
WHERE NOT EXISTS {
MATCH (fg)-[pf:PRODUCT_FLOW WHERE pf.globalBrand = "Calciiarottecarin"
AND pf.generation = "g2"
AND pf.form = "Caplet" // Filter: generation, form and strength of the drug
AND pf.strength = "50mg"
]->(:FG) // Ensure it's not part of a chained FG → FG flow
}
WITH fg, count(*) AS num
MATCH p = (fg)-[pf:PRODUCT_FLOW WHERE pf.globalBrand = "Calciiarottecarin"
AND pf.generation = "g2"
AND pf.form = "Caplet"
AND pf.strength = "50mg"
]->+ (dist:DIST:Product WHERE dist.globalBrand = fg.globalBrand
AND dist.generation = fg.generation
AND dist.strength = fg.strength
AND dist.form = fg.form)
WHERE EXISTS {
MATCH (dist)-[:DISTRIBUTED_BY]->(:Distributor) // Confirm product ends with a Distributor
}
WITH fg,
REDUCE(loc = [], x IN nodes(p)[0..-1] | loc + [split(x.location, "/")[1]]) AS countryList,
REDUCE(loc = [], x IN nodes(p)[0..-1] | loc + [x.location]) AS locationList,
REDUCE(loc = [], x IN nodes(p) | loc + [x.location]) AS fullLocList
WITH fg, countryList, locationList, fullLocList,
apoc.coll.dropDuplicateNeighbors(apoc.coll.sort(countryList)) AS dedupCountryList,
apoc.coll.dropDuplicateNeighbors(apoc.coll.sort(locationList)) AS dedupLocationList
WHERE
(countryList[0] = countryList[-1] AND size(dedupCountryList) > 1) // Cross-Border condition
OR
(locationList[0] = locationList[-1] AND size(dedupLocationList) > 1) // Cyclic condition
WITH fg, fullLocList,
CASE
WHEN countryList[0] = countryList[-1] AND size(dedupCountryList) > 1
THEN "Cross Border Shipment"
WHEN locationList[0] = locationList[-1] AND size(dedupLocationList) > 1
THEN "Cyclic Movement"
ELSE null
END AS costType
RETURN DISTINCT
costType,
fg.form AS form,
fg.generation AS gen,
fg.strength AS strength,
fullLocList AS LocationPath
ORDER BY fg.generation, fg.strength
|
您可以将一整套预保存的 Cypher 查询加载到 Neo4j Aura 查询工作区。 从 GitHub 仓库的
|
仪表盘 (使用 NeoDash)
Neo4j 仪表盘提供了药品供应链的交互式视图,帮助领导者在一个地方探索关键领域,如需求、瓶颈、可追溯性和设备使用情况。
准备工作
-
访问 https://neodash.graphapp.io/ 并点击“新建仪表盘”
-
点击“现有仪表盘”,因为仪表盘已保存在数据库备份中。
-
连接到步骤 1 中创建的数据库:数据库设置
-
点击底部的左箭头以展开左侧面板
-
点击“+”按钮并导入位于 GitHub 仓库
src文件夹中的 JSON 文件。
-
您应该会看到仪表盘
仪表盘选项卡
“供应链”选项卡提供了全球品牌、市场和分销的高级视图。例如,选择药物 Calciiarottecarin(50 毫克胶囊)会显示欧盟市场中丰富的需求,其中西欧是主要的经销商。从这里,您可以深入了解其完整的产品流,以评估上游依赖关系和潜在风险。
每个选项卡都侧重于一个关键维度:
-
“原材料需求”选项卡计算满足选定产品需求所需的原材料数量。它即时追溯供应链路径并汇总数量——使复杂的需**求传播变得简单且可扩展。
-
“供应链优化”选项卡有助于识别昂贵的运输模式和处理延迟。它揭示了跨境效率低下问题,并突出显示了超出目标持续时间的阶段——因此团队可以快速查明并解决瓶颈。
-
“批次追溯”选项卡有助于通过供应链追溯有缺陷的批次——揭示共享设备、操作员和潜在污染点。它结合了 Neo4j 丰富的关系建模和生成式 AI,以突出共性和根本原因,实现快速、可解释的调查。
-
“设备利用率”选项卡突出显示了生产中未充分利用的设备。借助 Neo4j 灵活的模式来建模流程和设备序列,它有助于识别重新安排的机会,以提高利用率,避免不必要的采购并计划维护。