Neo4J:具有过滤器的三级扩展节点

时间:2018-07-18 08:11:46

标签: performance neo4j cypher

对于新的POC,我有以下用例:

对于给定的节点,请执行三级扩展,但还要在所有扩展的节点上应用过滤器(意味着我要针对某些属性过滤所有结果节点)

测试集:

  • 节点:〜17 Mio
  • 边:〜40 Mio
  • 属性:〜2650 Mio

我的第一个解决方案如下:

MATCH path=(startNode:Entity {id:'RVDJRcV_yfXbG0-syGKp3Q..'})-[*..3]-(endNode:Entity) 
WITH path 
WHERE ALL (n IN nodes(path)[1..] 
WHERE n.key = '1' AND n.domain = 'facebook.com' AND n.investigationID='any') 
RETURN path 
LIMIT 100

这可以完成工作,但是速度不是很快。平均我的测试集中的查询时间是2-3秒,但超时很多(时间> 30秒)。我认为问题在于路径处理,并且我的节点具有很多属性...

说明计划: Explain plan

变体1:我删除了“ with path” Variant 1

解决方案: 根据提示,我应该在查询中避免使用[1 ..]

MATCH path=(startNode:Entity {id:'v-jXIO7kozAa35gMUpUkvg..'})-[*..3]-(endNode:Entity) 
WHERE ALL (n IN nodes(path)
WHERE n=startNode OR (n.key = '1' AND n.domain = 'facebook.com' AND n.investigationID='any')) 
RETURN path 
LIMIT 100

Solution

1 个答案:

答案 0 :(得分:1)

虽然您可以在扩展过程中使用可变长度路径进行过滤,但是当您使用列表的一部分而不是整个列表时,Cypher当前无法在扩展过程中应用该过滤器。它会退回到进行完整的var-length扩展,然后将滤波器应用于所有找到的结果。

我们只需要使用ALL (n IN nodes(path) ...,就不能使用路径的切片。

要执行此操作,我们需要在all()函数内添加一个谓词。由于起始节点可能不符合当前谓词,因此我们将为其创建一个例外:

MATCH path=(startNode:Entity {id:'RVDJRcV_yfXbG0-syGKp3Q..'})-[*..3]-(endNode:Entity) 
WHERE ALL (n IN nodes(path)[1..] 
 WHERE n=startNode OR (n.key = '1' AND n.domain = 'facebook.com' AND n.investigationID='any')) 
RETURN path 
LIMIT 100