知识图谱通过在图数据库中组织事件、人物、资源和文档,实现对复杂分析的支持。本文将解释知识图谱的目的,并展示如何将关系数据模型转化为图模型,将数据加载到图数据库,并编写一些示例图查询。
#01
为什么需要知识图谱
关系数据库适用于创建列表,但对于管理各种实体网络效果并不理想。你是否也曾像我一样处理过类似下面的这些任务?
分析患者与数十名相关人员、地点和程序互动的医疗护理事件
在涉及各种供应商、客户和交易类型的网络中查找金融欺诈模式
优化供应链的依赖关系和相互连接的元素
这些都是事件、人物和资源网络的例子,这些复杂的关联关系给使用关系数据库的 SQL 分析师甚至是开发人员带来了巨大的麻烦。而随着业务规模的增加,关系数据库的性能会呈指数级下降,而图数据库则具有相对线性的关系。如果你正在管理一个由活动和事物组成的网络,那图形数据库可能是正确的选择。在未来,我们应该可以看到企业数据采用关系数据库组合,他们对一个业务功能进行隔离分析,以及知识图谱用于跨功能的复杂网络流程。
基于图数据库技术的知识图谱用于处理各种流程和实体网络。在知识图谱中,你有代表人物、事件、地点、资源、文档等的节点。并且您具有表示节点之间链接的关系(边)。这些关系以物理方式存储在数据库中,并具有名称和方向。并非每个图数据库都是知识图谱。要被视为知识图谱,设计必须将业务语义模型嵌入到跨越多个业务功能的各种节点中,该模型反映在节点和关系的清晰业务名称中。从本质上讲,您正在从业务的所有交互部分创建一个无缝的 Web,并使用业务语义将数据与它们所代表的流程紧密联系起来。这可以作为未来生成式 LLM 模型使用的基础。
为了说明知识图谱中的多样数据集,让我们看一个供应链物流的简单示例。业务流程可能被建模如下:

该模型可以扩展,它包括与业务流程相关的任何相关部分:客户退货、发票、原材料、制造过程、员工,甚至客户评论。模型没有预定义的架构,因此可以朝任何方向或深度扩展。
#02
从关系模型到维度模型再到图模型
我们使用电子商务供应商的情景,将典型的关系数据库模型转化为图模型。假设这个供应商正在进行一系列数字营销活动,在其网站上接收订单并向客户发货。关系模型可能如下所示:

如果我们将其转换为数据仓库中使用的维度模型,该模型可能如下所示:

请注意,事实表侧重于事件,维度表表示将业务实体的所有属性组合成一个表。这种以事件为中心的设计可以提高查询速度,但也带来其他问题。每个事件都是一个独立的事实表,从一个事件到相关事件的连接很难看到。在将这些关系拆分到多个事实表之间,很难理解维度实体(如产品)与在另一个维度中的实体(如运营商)共享的所有事件之间的关系。维度模型专注于一次处理一个事件,但模糊了不同事件之间的连接。
图模型通过以下方式解决了在实体之间显示相互关系的问题:

乍一看,这个图模型与关系模型更相似,但它确实是维度模型,它可以用于与数据仓库相同的分析目的。而且,你会发现,每个关系都有名称和方向。关系可以在任何节点之间创建 - 事件到事件,人到人,文档到事件等。图查询还允许你使用 SQL 无法实现的方式遍历图形。
例如,您可以收集与关键事件相关的任何节点,并研究发生模式。与非规范化维度表不同,将保留层次结构,并且可以单独引用每个级别。最重要的是,图形在对业务中的任何事件或实体进行建模时更加灵活,而无需遵循一组严格的模式约束。该图旨在匹配业务的语义模型。
#03
提取、转换和加载(ETL)
现在让我们看一个样本关系数据库表,并创建一些示例脚本来提取、转换和加载数据到图数据库。在本文中,我使用 Cypher 语言(该语言被最流行的商业图形数据库 Neo4j 使用)。这些概念也适用于其他图查询语言(GQL)。我们将使用以下样本 Product :
+------------+--------------+-----------+----------------+-------------------+| product_id | product_name | cost_usd | product_status | last_updated_date |+------------+--------------+-----------+----------------+-------------------+| 5432 | Velvet sofa | 325.00 | Active | 2023-05-03 |+------------+--------------+-----------+----------------+-------------------+| 5433 | dining chair | 125.00 | Active | 2023-05-15 |+------------+--------------+-----------+----------------+-------------------+| 5434 | Mailbox | 204.00 | Inactive | 2023-11-04 |+------------+--------------+-----------+----------------+-------------------+
使用此查询,我们可以提取过去24小时内更新的新产品:
-- Pull new products updated in the last 24 hoursSELECT product_id,product_name,cost_usd,product_statusFROM ProductWHERE last_updated_date > current_date - 1;
我们可以将这些结果提取到名为“df”的 Python Pandas 数据帧中,打开图形数据库连接,然后使用此脚本将数据帧合并到图形中
-- Cypher script to merge the dataframe into the graphUNWIND $df as rowMERGE INTO (p:Product {product_id: row.product_id})SET p.product_name = row.product_name,p.cost_usd = row.cost_usd,p.product_status= row.product_status,p.last_updated_date = datetime();
第一行引用参数“df”,该参数是来自 Pandas 的数据帧。我们将合并到节点类型“Product”中,该节点由别名“P”引用。然后,“product_id”部分用于绑定到节点中的唯一标识符。之后,Merge 语句看起来类似于 SQL 中的合并。
使用上述合并语句创建每个节点后,我们将创建关系。关系可以在同一脚本中创建,也可以使用合并命令在后处理脚本中创建,如下所示:
-- Cypher script to create relationships between nodesMATCH (p:Product), (o:Order)WHERE p.product_id = o.order_idMERGE (o)-[:CONTAINS]->(p);
Match 语句类似于 Mysql 中的传统联接用法,在 Match 之后声明了两种节点类型,然后在 Where 子句中发生了联接。
#04
图模型上的查询
假设我们已经构建了图形,现在想要查询它。我们可以使用这样的查询来。
-- Cypher query to find Ad Groups that have driven orders from ArizonaMATCH (ag:AdGroup)<-[:BELONGS_TO]-(a:Ad)-[:DRIVES]->(o:Order)<-[:PLACES]-(c:Customer)WHERE c.state = 'AZ'RETURN ag.group_name,COUNT(o) as order_count
这个查询将返回广告组名称和订单数。要注意的是,与 SQL 不同,Cypher 中不需要 Group By 子句。从该查询中,我们将收到以下示例输出:
+----------------------+------------+| group_name | order_count|+----------------------+------------+| Fall furniture Sale | 15 |+----------------------+------------+| Fall Housewares | 32 |+----------------------+------------+| Fall 15% off | 301 |+----------------------+------------+
这个示例可能看起来没啥,因为您可以使用订单事实数据表轻松地在关系数据库或数据仓库中创建类似的查询。假设您想要查看从广告系列启动到收到可归因投放所需的时间。在数据仓库中,此查询将跨事实数据表(不是简单的任务)并占用大量资源。在关系数据库中,此查询将涉及一长串联接。在图形数据库中,查询如下所示:
-- Cypher query to see the time it takes from the launch of a campaign until the attributable deliveries have been receivedMATCH (cp:Campaign) )<-[:BELONGS_TO]-(ag:AdGroup)<-[:BELONGS_TO]-(a:Ad)MATCH (a)-[:DRIVES]->(o:Order)<-[:FULFILLS]-(d:Delivery)RETURN cp.campaign_name,cp.start_date as campaign_launch_date,MAX(d.receive_date) as last_delivery_date
我使用了一个示例查询路径,但用户可以采用多种路径来回答不同的业务问题。在查询中,请注意,从Campaign到Delivery的路径会经历Order和Delivery之间的关系。另请注意,为了便于阅读,我将路径分为两部分,从第二行中 Ad 的别名开始。查询的输出如下所示:
+----------------------+----------------------+----------------------+| campaign_name | campaign_launch_date | last_delivery_date |+----------------------+----------------------+----------------------+| Fall Direct Response | 2023-01-01 | 2023-01-10 |+----------------------+----------------------+----------------------+| Fall Branding | 2023-03-15 | 2023-03-25 |+----------------------+----------------------+----------------------+| Fall Product Launch | 2023-03-15 | 2023-03-25 |+----------------------+----------------------+----------------------+
#05
结论
我们已经查看了一些将电子商务业务流程从关系模型转换为图形模型的示例步骤,但我们无法在本文中涵盖所有设计原则。希望您已经看到图形数据库需要与关系数据库大致相同的技术技能水平,并且迁移并不是一个巨大的障碍。
最大的挑战是重新训练你的大脑,远离传统的关系建模技术,从语义或业务建模的角度思考。如果您看到图形技术的潜在应用,请尝试概念验证项目。使用知识图谱进行分析的可能性远远超出了使用二维表格所能做到的
#06
参考链接
neo4j:https://neo4j.com/
GQL:https://www.gqlstandards.org/
欢迎添加 二师兄 的个人微信 沟通交流(请勿重复添加)

请用个人微信添加




