Neo4j自我网络查询优化

问题描述

我想查询给定节点的自我网络。我当前的代码耗时将近1秒。在具有42k节点和200万边缘的数据库上返回4k行。这似乎非常慢。我该如何优化呢?

Topic.name上有唯一的约束/索引。

查询

match (n:Topic)-[e]-(m: Topic) 
where n.name = 'raman'
with collect(m.name) as ms,n
match (m1:Topic)-[e]-(m2:Topic)
where (m1.name in ms or m1.name = n.name) and (m2.name in ms or m2.name = n.name) and m1.name < m2.name
return m1.name,m2.name,e.weight;

执行配置文件

Query executed in 842ms. Query type: READ_ONLY.
Profile:
----------> NodeUniqueIndexSeek@neo4j[records: 1; dbHits: 2] {identifiers: [n]; arguments: {Order="n.name ASC",PageCacheHitRatio=0.0,Details="UNIQUE n:Topic(name) WHERE name = $autostring_0,cache[n.name]",PageCacheMisses=0,EstimatedRows=1.0,DbHits=2,Rows=1,PageCacheHits=0}}
---------> Expand(All)@neo4j[records: 179; dbHits: 180] {identifiers: [n,e,m]; arguments: {Order="n.name ASC",Details="(n)-[e]-(m)",EstimatedRows=95.69165595671438,DbHits=180,Rows=179,PageCacheHits=0}}
--------> Filter@neo4j[records: 179; dbHits: 179] {identifiers: [n,Details="m:Topic",DbHits=179,PageCacheHits=0}}
-------> EagerAggregation@neo4j[records: 1; dbHits: 179] {identifiers: [n,ms]; arguments: {PageCacheHitRatio=0.0,Details="n,collect(m.name) AS ms",Memory=11448,EstimatedRows=9.782211199760225,PageCacheHits=0}}
----------> NodeUniqueIndexSeek@neo4j[records: 179; dbHits: 358] {identifiers: [n,ms,m1]; arguments: {PageCacheHitRatio=0.0,Details="UNIQUE m1:Topic(name) WHERE name IN ms,cache[m1.name]",EstimatedRows=244.48469730942983,DbHits=358,PageCacheHits=0}}
----------> NodeUniqueIndexSeek@neo4j[records: 1; dbHits: 3] {identifiers: [n,Details="UNIQUE m1:Topic(name) WHERE name = cache[n.name],DbHits=3,PageCacheHits=0}}
---------> Union@neo4j[records: 180; dbHits: 0] {identifiers: [n,EstimatedRows=254.26690850919005,DbHits=0,Rows=180,PageCacheHits=0}}
--------> distinct@neo4j[records: 180; dbHits: 0] {identifiers: [n,m1",Memory=2143856,EstimatedRows=254.2610272318913,PageCacheHits=0}}
----------> NodeUniqueIndexSeek@neo4j[records: 32220; dbHits: 64440] {identifiers: [n,m2]; arguments: {PageCacheHitRatio=0.0,Details="UNIQUE m2:Topic(name) WHERE name IN ms,cache[m2.name]",DbHits=64440,Rows=32220,PageCacheHits=0}}
----------> NodeUniqueIndexSeek@neo4j[records: 180; dbHits: 540] {identifiers: [n,Details="UNIQUE m2:Topic(name) WHERE name = cache[n.name],DbHits=540,PageCacheHits=0}}
---------> Union@neo4j[records: 32400; dbHits: 0] {identifiers: [n,Rows=32400,PageCacheHits=0}}
--------> distinct@neo4j[records: 32400; dbHits: 0] {identifiers: [n,m2",PageCacheHits=0}}
-------> CartesianProduct@neo4j[records: 32400; dbHits: 0] {identifiers: [n,m1,EstimatedRows=6608.799242711218,PageCacheHits=0}}
------> Apply@neo4j[records: 32400; dbHits: 0] {identifiers: [n,EstimatedRows=0.45638084942956914,PageCacheHits=0}}
-----> CacheProperties@neo4j[records: 32400; dbHits: 0] {identifiers: [n,Details="cache[m2.name],PageCacheHits=0}}
----> Expand(Into)@neo4j[records: 7848; dbHits: 5431444] {identifiers: [e,m2,n,Details="(m1)-[e]-(m2)",Memory=2688168,EstimatedRows=15.21306094348127,DbHits=5431444,Rows=7848,PageCacheHits=0}}
---> Filter@neo4j[records: 3924; dbHits: 0] {identifiers: [e,Details="cache[m1.name] < cache[m2.name]",Rows=3924,PageCacheHits=0}}
--> Projection@neo4j[records: 3924; dbHits: 3924] {identifiers: [e,`e.weight`,`m2.name`,`m1.name`]; arguments: {PageCacheHitRatio=0.0,Details="cache[m1.name] AS `m1.name`,cache[m2.name] AS `m2.name`,e.weight AS `e.weight`",DbHits=3924,PageCacheHits=0}}
-> ProduceResults@neo4j[records: 3924; dbHits: 0] {identifiers: [e,GlobalMemory=6986840,planner-impl="IDP",runtime="INTERPRETED",runtime-impl="INTERPRETED",version="CYPHER 4.1",Details="`m1.name`,`e.weight`",planner-version="4.1",runtime-version="4.1",planner="COST",PageCacheHits=0}}

enter image description here

谢谢!

解决方法

根据您对建立自我网络的评论,我会尝试这样的事情:

MATCH (n:Topic)
WHERE n.name = 'raman'
MATCH p=(n)-[*1..2]-(m:Topic)
WHERE (n)--(m)
WITH p
UNWIND relationships(p) as rel
WITH collect(distinct rel) as rels
UNWIND rels as r
RETURN startNode(r).name,endNode(r).name,r.weight