優化互動網絡推薦圖遍歷規則-圖加載速度進入毫秒級別

需要解決的問題:局部圖譜規模達到百萬級別之後多層關係遍歷出現性能問題;CYPHER使用CONTIANS關鍵字檢索性能太差。
取得的成果:通過下述方式進行優化之後,關係分析查詢耗時從原來的30s左右,降低到ms級別;關鍵字檢索耗時降低到ms級,已經可以滿足業務需求。

互動網絡分析優化

一、優化互動網絡加載

局部圖譜數據規模百萬級別,總體數據規模達到數千萬級別

  1. 原始查詢
<!--耗時:都在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;
  1. 優化後查詢
<!--耗時:都在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;

二、互動網絡關係溯源圖加載優化

  1. 原始查詢
<!--耗時:都在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; 
  1. 優化後查詢
<!--耗時:都在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百萬

  1. 原始查詢
<!--耗時:都在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;
  1. 優化後查詢
<!--創建全文索引-->
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

自定義存儲過程源碼

發佈了166 篇原創文章 · 獲贊 113 · 訪問量 29萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章