Here’s the table of contents:

快速获取子图根节点的属性

    子图查找匹配是一个非常复杂的问题,主要有确定模式的子图匹配不确定模式的子图匹配【例如:通过图模式相似性进行查找】。本文主要讲述一个确定模式的子图查询方式,对于存在很多子图的数据模型也可以使用本文截图中社区成员提问的方式去建模数据可以达到节省资源空间的目的;不过具体建模场景需要结合业务场景才可行。已知子图查找问题可以使用APOC中的过程来实现,apoc.path相关输入输出查询;指定节点之后获取节点所属的子图,然后从子图中提取出ROOT节点的属性。

一、问题背景

二、构建样例多子图数据

    构建a、b、c、d、e、f六个节点,并使用Follow关系将节点关联在一起,形成一个自定义子图。其中指定a节点为ROOT节点即子图的根节点。

MERGE (a:Child {name:'a'}) SET a.subname='root'
MERGE (b:Child {name:'b'}) 
MERGE (c:Child {name:'c'}) 
MERGE (d:Child {name:'d'}) 
MERGE (e:Child {name:'e'}) 
MERGE (f:Child {name:'f'}) 
MERGE (a)-[:Follow]->(b)
MERGE (a)-[:Follow]->(c)
MERGE (b)-[:Follow]->(d)
MERGE (b)-[:Follow]->(e)
MERGE (c)-[:Follow]->(f)

在这里插入图片描述

三、实现根节点的属性查找

    在中构建好了样例子图数据,下面实现从样例子图中任意某个节点出发寻找ROOT节点。

MATCH (n:Child) WHERE n.name='e'
CALL apoc.path.expand(n,'Follow',NULL,0,6) YIELD path WITH COLLECT(path) AS subGraph
UNWIND subGraph AS p
WITH nodes(p) AS nodes
UNWIND nodes AS node
WITH node
WHERE EXISTS(node.subname)
RETURN node

    查询的运行结果如下,顺利找到了我们预先设计的a节点,即我们需要查找的ROOT节点。

在这里插入图片描述

四、将子图查找的GQL封装为一个函数

    对于一个复杂的查询,通常需要隐藏其实现细节方便业务调用。下面通过apoc.custom.asFunction这个过程,实现了将中的复杂查询进一步封装的目的。调用时只需要使用custom.subGraphRootName($para)这个函数即可。

CALL apoc.custom.asFunction(
  	'subGraphRootName',
  	'MATCH (n:Child) WHERE n.name=$nodeName CALL apoc.path.expand(n,\'Follow\',NULL,0,6) YIELD path WITH COLLECT(path) AS subGraph UNWIND subGraph AS p WITH nodes(p) AS nodes UNWIND nodes AS node WITH node WHERE EXISTS(node.subname) RETURN node',
  	'STRING',
  	[['nodeName','STRING']],
  	FALSE,
  	'获取指定节点所属的根节点,并返回根节点的subname属性'
);
RETURN custom.subGraphRootName('e') AS rootSubName;

在这里插入图片描述

五、总结

    本文通过一个非常简单的场景,介绍了一个子图分析的方法。实际生产中面临的问题可能会比这个更加复杂,需要综合考虑数据写入性能、数据查询性能、数据服务易用性等多方面的因素。数据优化本文中提到的只是冰山一角,沧海一粟,需要不断地在实战中打磨演练。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐