@TOC[1] Here's the table of contents:
•一、问题背景•二、构建样例多子图数据•三、实现根节点的属性查找•四、将子图查找的GQL封装为一个函数•五、总结
快速获取子图根节点的属性
子图查找匹配是一个非常复杂的问题,主要有
确定模式的子图匹配
和不确定模式的子图匹配
【例如:通过图模式相似性进行查找】。本文主要讲述一个确定模式的子图查询方式,对于存在很多子图的数据模型也可以使用本文截图中社区成员提问的方式去建模数据可以达到节省资源空间的目的;不过具体建模场景需要结合业务场景才可行。已知子图查找问题可以使用APOC中的过程来实现,apoc.path相关输入输出查询[2];指定节点之后获取节点所属的子图,然后从子图中提取出ROOT节点的属性。
一、问题背景
•社区问题链接[3]
二、构建样例多子图数据
代码语言:javascript复制构建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)
三、实现根节点的属性查找
代码语言:javascript复制在
二
中构建好了样例子图数据,下面实现从样例子图中任意某个节点出发寻找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封装为一个函数
代码语言:javascript复制对于一个复杂的查询,通常需要隐藏其实现细节方便业务调用。下面通过
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属性'
);
代码语言:javascript复制RETURN custom.subGraphRootName('e') AS rootSubName;
五、总结
本文通过一个非常简单的场景,介绍了一个子图分析的方法。实际生产中面临的问题可能会比这个更加复杂,需要综合考虑数据写入性能、数据查询性能、数据服务易用性等多方面的因素。数据优化本文中提到的只是
冰山一角,沧海一粟
,需要不断地在实战中打磨演练。
References
[1]
TOC: 快速获取子图根节点的属性
[2]
apoc.path相关输入输出查询: https://neo4j.com/labs/apoc/4.3/overview/apoc.path/apoc.path.expand/
[3]
社区问题链接: http://neo4j.com.cn/topic/60a8ce1fbbf352cc76a8d59e