我想按度数排列节点 - 为什么这个 Neo4J Cypher 请求这么慢?

问题描述

我想首先将某种类型的所有节点连接到一个上下文,然后简单地按它们的程度对它们进行范围划分,但仅限于与属于同一上下文的其他节点的 (:TO) 类型的连接。我尝试了几种方法包括下面的方法,但它们太慢了(10 秒)。有什么办法可以让它更快吗?

MATCH (ctx:Context{uid:'60156a60-d3e1-11ea-9477-f71401ca7fdb'})<-[:AT]-(c1:Concept) 
WITH c1 MATCH (c1)-[r:TO]-(c2:Concept) 
WHERE r.context = '60156a60-d3e1-11ea-9477-f71401ca7fdb' 
RETURN c2,count(r) as degree ORDER BY degree DESC LIMIT 10;
MATCH (ctx:Context{uid:'60156a60-d3e1-11ea-9477-f71401ca7fdb'})<-[:AT]-(c1:Concept)-[:TO]-(c2:Concept) 
RETURN c1,count(c2) as degree 
ORDER BY degree DESC LIMIT 10;

解决方法

检查程度的一种方法是使用大小函数,您是否尝试过这样的方法?

 size((c1)-[:TO]-(:Concept))

在我的图中 size() 似乎更有效,但它也可能是我的密码重新排列。

示例:(在我的图表中)此语句是 81db 命中

PROFILE MATCH (g:Gene {name:'ACE2'})-[r:EXPRESSED_IN]-(a)
return  count(r)

这是 4 db hit

PROFILE MATCH (g:Gene {name:'ACE2'})
return size((g)-[:EXPRESSED_IN]-())

我不确定下一个建议是否更快/更有效,但如果您总是在单个关系或关系子集上计算度数,您可能会考虑存储度数值,以查看这是否可能是一个选项(更快?).

我在批量加载后立即对整个图表执行此操作

CALL apoc.periodic.iterate(
"MATCH (n) return n","set n.degree = size((n)--())",{batchSize:50000,batchMode: "BATCH",parallel:true});

但出于不同的原因,我想在 neo4j 浏览器中查看度数值(例如...)注意:我每天从头开始重建我的图表,但在下一次重建之前它是静态的