梁敬彬梁敬弘兄弟出品
往期回顾
七座城堡⓵ OLTP(上)
七座城堡⓵ OLTP(下)
七座城堡② OLAP(上)
七座城堡② OLAP(下)
七座城堡③ HTAP(上)
七座城堡③ HTAP(下)
七座城堡④ 时序(上)
七座城堡④ 时序(下)
七座城堡⑤ 图(上)
20. 图数据库城堡的诞生
老柯:老王,我觉得我们要换一个思路来解决这个问题,可以尝试使用图数据库来处理这种复杂的查询。
就在大家一筹莫展时候,老柯想起来自己曾经阅读过的技术文献,忽然有了思路。
老王:图数据库?
老柯:图数据库是一种专门用来存储和处理对象之间的关系的数据库,它可以直观地展示对象间的关系,与关系型数据库有着很大的差异,是以节点(Node)和边(Edge)为核心构建的。节点代表实体,比如人或事物,边则代表节点之间的关系。
在这个模型中,查询复杂关系就变得相对简单了,因为它们本质上就是图遍历问题。非常适合处理这种复杂的关系查询。不过有趣的一点是,这个图数据库是一种处理关系的非关系型数据库,我们将要采用的架构是NoSQL架构,之前我说的KV数据库是NoSQL的一类产品,而这个图数据库是NoSQL的另一类产品。
老王:我听明白了,真是大开眼界!那我们该怎么做,建一个图数据库城堡?
老柯:是的,我们建一座图数据库城堡,把相关的数据同步到图数据库城堡来,然后转化成图数据库的格式,就可以找到有缘人了。且不说王子成婚时一件国家大事,这个城堡一旦建立起来,还是可以在很多领域的,比如社交网络分析、欺诈行为检测、知识图谱、生命科学探索、推荐系统等等,其实是大有作用的。此外,咱们如果能通过图数据库城堡找到这个有缘人,将来是不是就更有可能通过各种关联关系的蛛丝马迹,抓到老安团伙。
老王:好,那就拜托你了,请务必以最快的速度打造一个图数据库城堡。
老柯的一番话听的老王眼睛一亮,当即决定再打造一座全新的城堡。由于有了大量建数据库城堡的经验,此次城堡的建立创造了奇迹,以不可思议的速度建造完成。
21. 终于找到缘人
老王第一时间赶到图数据库城堡,为了验证图数据库城堡的威力和效果,依然从有缘人1开始找起,老柯
开始边分步骤演示,并展开了详细的说明。
步骤1,查找国王和王子的共同朋友。
需要注意的,这里通过使用 MATCH 关键字来查找符合特定模式的数据。在这里,我们查找名为"King"的人(国王)与名为"Prince"的人(王子)共同的朋友。我们通过:FRIEND关系连接他们,并将共同的朋友存在common_friend变量中。代码如下:
MATCH (king:Person {name: 'King'})-[:FRIEND]->(common_friend:Person)<-[:FRIEND]-(prince:Person {name: 'Prince'})
步骤2,查找国王和找有缘人在同一位医生那里接受过治疗。
此处想要找到国王和其他人(用p表示)在同一位医生(doctor)那里接受过治疗。我们用:TREATED_BY 关系来表示这种联系。代码如下:
MATCH (king)-[:TREATED_BY]->(doctor:Doctor)<-[:TREATED_BY]-(p:Person)
步骤3,确保有缘人与国王的顾问在同一所学校接受过教育。这里,我们使用:
MATCH (king)-[:HAS_ADVISOR]->(advisor:Person)-[:STUDIED_AT]->(school:School)<-[:STUDIED_AT]-(p)
步骤4,同时需要排除国王和王子与找有缘人之间的直接朋友关系。
注意此处使用 WHERE NOT语句来排除这些直接关系。代码如下:
WHERE NOT (king)-[:FRIEND]->(p) AND NOT (prince)-[:FRIEND]->(p)
步骤5,计算每个找有缘人担任过的不同工作岗位数量。
我们使用 WITH 关键字将查询结果传递到下一步。然后计算每个找有缘人担任过的不同工作岗位数量,并将结果存储在 job_count 变量中。代码如下:
WITH p, COUNT(DISTINCT (p)-[:WORKED_AS]->(:Job)) AS job_count
步骤6,确保每个找有缘人担任过的不同工作岗位至少有5个。
在这里,我们对job_count 进行筛选,确保符合条件的找有缘人至少担任过5个不同的工作岗位。代码如下:
WHERE job_count >= 5
步骤7,返回满足所有条件的找有缘人的名字。
这是最后一步,我们使用RETURN关键字返回所有满足条件的找有缘人(p)的名字,代码如下:
RETURN p.name;
以上所有这些思路合并在一起,我们得到了这个完整的SQL指令,代码如下:
// 查找国王和王子的共同朋友
MATCH (king:Person {name: 'King'})-[:FRIEND]->(common_friend:Person)<-[:FRIEND]-(prince:Person {name: 'Prince'})
// 查找国王和找有缘人(用p表示)在同一位医生那里接受过治疗
MATCH (king)-[:TREATED_BY]->(doctor:Doctor)<-[:TREATED_BY]-(p:Person)
// 确保找有缘人与国王的顾问在同一所学校接受过教育
MATCH (king)-[:HAS_ADVISOR]->(advisor:Person)-[:STUDIED_AT]->(school:School)<-[:STUDIED_AT]-(p)
// 排除国王和王子本身与找有缘人之间的朋友关系
WHERE NOT (king)-[:FRIEND]->(p) AND NOT (prince)-[:FRIEND]->(p)
// 计算每个找有缘人担任过的不同工作岗位数量
WITH p, COUNT(DISTINCT (p)-[:WORKED_AS]->(:Job)) AS job_count
// 确保每个找有缘人担任过的不同工作岗位至少有5个
WHERE job_count >= 5
// 返回满足所有条件的找有缘人的名字
RETURN p.name;
在众人期待的目光下,指令发出了,第一个有缘人信息极短时间内即返回,人群欢呼雀跃。很快,盒子的十层全部被打开了,真正的有缘人的名字和地址水落石出。
老王欣喜若狂,当即派出商务大臣前去邀请有缘人以征婚人的身份来参加王子的婚礼,同时老王对外宣称王子的婚礼将在图数据库城堡举行。
未完待续…
七座城堡⑥ GIS(上)
系列回顾