赞
踩
需要解决的问题:局部图谱规模达到百万级别之后多层关系遍历出现性能问题;CYPHER使用CONTIANS关键字检索性能太差。
取得的成果:通过下述方式进行优化之后,关系分析查询耗时从原来的30s左右,降低到ms级别;关键字检索耗时降低到ms级,已经可以满足业务需求。
局部图谱数据规模百万级别,总体数据规模达到数千万级别
<!--耗时:都在30s左右-->
<!--10 rows available after 33396 ms, consumed after another 0 ms-->
<!--10 rows available after 32161 ms, consumed after another 0 ms-->
<!--10 rows available after 37264 ms, consumed after another 1 ms-->
MATCH p=(n)-->(post)<--(m) WHERE id(n)=5951 AND zdr.apoc.targetNodesRelasFilter(relationships(p),['隶属虚拟账号','发帖','点赞','评论','转发','回复','互动'],NULL,NULL)=true WITH m AS node,count(*) AS count ORDER BY count DESC SKIP 100 LIMIT 10 SET node.interactiveNetworkAnalyzerCount=count RETURN node;
<!--耗时:都在90ms左右-->
<!--10 rows available after 88 ms, consumed after another 0 ms-->
<!--10 rows available after 92 ms, consumed after another 1 ms-->
<!--10 rows available after 81 ms, consumed after another 0 ms-->
MATCH (n) WHERE id(n)=5951 WITH n
CALL apoc.path.subgraphNodes(n,{maxDepth:2,relationshipFilter:'隶属虚拟账号|发帖|点赞|评论|转发|回复|互动',labelFilter:'-专题事件|/虚拟账号ID|/新浪微博ID|/网易博客ID|/新浪博客ID|/腾讯微博ID|/TwitterID|/百度贴吧ID|/天涯论坛ID|/微信公众号ID|/FacebookID|/LinkedinID|/YouTubeID|/InstagramID',limit:10}) YIELD node WITH node,n
MATCH p=(n)-->(post)<--(node) WHERE zdr.apoc.targetNodesRelasFilter(relationships(p),['隶属虚拟账号','发帖','点赞','评论','转发','回复','互动'],NULL,NULL)=true WITH node,count(p) AS count ORDER BY count DESC SKIP 0 LIMIT 10 SET node.interactiveNetworkAnalyzerCount=count RETURN node;
<!--耗时:都在40s左右-->
<!--4 rows available after 8 ms, consumed after another 45265 ms-->
<!--4 rows available after 66 ms, consumed after another 40844 ms-->
<!--4 rows available after 8 ms, consumed after another 46207 ms-->
MATCH p=(n)-[*..2]->(post)<--(m) WHERE id(n)=5951 AND id(m) IN [1438375,1438333] AND zdr.apoc.targetNodesRelasFilter(relationships(p),['隶属虚拟账号','发帖','点赞','评论','转发','回复','互动'],NULL,NULL)=true RETURN p;
<!--耗时:都在1ms左右-->
<!--4 rows available after 1 ms, consumed after another 1 ms-->
<!--4 rows available after 2 ms, consumed after another 1 ms-->
<!--4 rows available after 0 ms, consumed after another 1 ms-->
MATCH (n),(m) WHERE id(n)=5951 AND id(m) IN [1438375,1438333] WITH n,m AS node
MATCH p=(n)-->(post)<--(node) WHERE zdr.apoc.targetNodesRelasFilter(relationships(p),['隶属虚拟账号','发帖','点赞','评论','转发','回复','互动'],NULL,NULL)=true RETURN p;
数据量400百万
<!--耗时:都在40s左右-->
<!--6 rows available after 5835 ms, consumed after another 34145 ms-->
<!--6 rows available after 4993 ms, consumed after another 32139 ms-->
<!--6 rows available after 5233 ms, consumed after another 32832 ms-->
MATCH (n:新浪微博ID) WHERE n.nameNodeSpace CONTAINS '中国共产党' RETURN n LIMIT 200;
<!--创建全文索引-->
CALL db.index.fulltext.createNodeIndex('新浪微博ID',["新浪微博ID"],["nameNodeSpace"]);
<!--耗时:都在700ms左右-->
<!--200 rows available after 1014 ms, consumed after another 24 ms-->
<!--200 rows available after 750 ms, consumed after another 5 ms-->
<!--200 rows available after 542 ms, consumed after another 24 ms-->
CALL db.index.fulltext.queryNodes('新浪微博ID', '中国共产党') YIELD node RETURN node SKIP 0 LIMIT 200;
1、搜索子图
<!--参数说明:--> <!--startNode:节点或节点列表--> <!--{configuration}的配置:--> <!--maxDepth INT 最大遍历层数--> <!--relationshipFilter STRING 关系过滤器--> <!--labelFilter STRING 标签过滤器--> <!--bfs BOOLEAN true-宽度优先遍历 false-广度优先遍历--> <!--filterStartNode BOOLEAN 是否对起始节点应用过滤规则--> <!--limit INT 返回路径的数目上限--> <!--optional BOOLEAN false-没找到符合条件的路径,则不返回--> <!--endNodes 节点列表 遍历终止节点列表--> <!--terminatorNodes 节点列表 终止节点列表--> <!--sequence 字符串 配置此项关系与标签过滤规则会被忽略--> <!--beginSequenceAtStart 是否对起始节点应用sequence中定义的规则--> <!--{maxDepth:2,relationshipFilter:'发帖|点赞|评论|转发|回复',labelFilter:'/新浪微博ID',bfs:false,filterStartNode:false,limit:-1,optional:false}--> CALL apoc.path.subgraphNodes(startNode,{configuration}) YIELD node; CALL apoc.path.subgraphAll(startNode,{configuration}) YIELD nodes, relationships;
2、路径扩展
搜索子图的过程不会遍历所有可能的路径(即节点和边的所有可能序列),因此在执行效率和成本方面都优于路径扩展过程。
<!--▪ startNode:起始节点,可以是节点的Id或者节点变量--> <!--▪ relationshipFilter:遍历关系的过滤条件,用‘|’分隔--> <!--▪ labelFilter:遍历节点的过滤条件,用’|’分隔(见下页)--> <!--▪ minLevel:最小遍历层级--> <!--▪ maxLevel:最大遍历层级--> <!--pathFilter:--> <!--‘PARENT_OF>|ANSWER’:遍历仅沿着这两个关系进行,其中PARENT_OF是有向的(从Post离开的),ANSWER是双向的--> <!--labelFilter:--> <!---Post 排除 Post节点不被遍历,也不被包括在返回的路径中。--> <!--+Post 包含 缺省。Post节点将被遍历,也被包括在返回的路径中。--> <!--/Post 终止且返回 遍历路径直到遇见Post类型的节点,然后仅返回Post节点。--> <!-->Post 终止但是继续 遍历路径只返回到达Post类型的节点(含)之前的部分,在Post节点之后的部分会继续被遍历,但是不会被返回。--> CALL apoc.path.expand(startNode,relationshipFilter,labelFilter,minLevel,maxLevel) YIELD path <!--▪ startNode 起始节点列表--> <!--▪ {configuration}的配置:--> <!--▪ minDepth INT 最小遍历层数--> <!--▪ maxDepth INT 最大遍历层数 -1不限制--> <!--▪ relationshipFilter STRING 关系过滤器--> <!--▪ labelFilter STRING 标签过滤器--> <!--▪ bfs BOOLEAN true-宽度优先遍历 false-广度优先遍历--> <!--▪ uniqueness STRING 唯一性规则--> <!--▪ filterStartNode BOOLEAN 是否对起始节点应用过滤规则--> <!--▪ limit INT 返回路径的数目上限--> <!--▪ optional BOOLEAN false-没找到符合条件的路径,则不返回--> <!--▪ endNodes 节点列表 遍历终止节点列表--> <!--▪ terminatorNodes 节点列表 终止节点列表--> <!--▪ sequence 字符串 配置此项关系与标签过滤规则会被忽略--> <!--▪ beginSequenceAtStart 是否对起始节点应用sequence中定义的规则--> CALL apoc.path.expandConfig(startNode <id>|Node|list, {minLevel,maxLevel,uniqueness,relationshipFilter,labelFilter,uniqueness:'RELATIONSHIP_PATH',bfs:true, filterStartNode:false, limit:-1, optional:false, endNodes:[], terminatorNodes:[], sequence, beginSequenceAtStart:true}) yield path YIELD path
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。