如何在Neo4j中有效地过滤多个过程调用的结果

时间:2016-08-01 20:07:56

标签: neo4j neo4j-spatial graphaware

我有一个GraphAware时间树和空间r树设置为引用我的图中的一大组节点。我试图按时间和空间搜索这些记录。

我个人可以在大约5秒钟内收集这些查询的结果:

WITH
({start:1300542000000,end:1350543000000}) as tr
CALL ga.timetree.events.range(tr) YIELD node as n
RETURN count(n);
> ~ 500000 results

WITH
({lon:120.0,lat:20.0}) as smin, ({lon:122.0,lat:21.0}) as smax
CALL spatial.bbox('spatial_records', smin, smax) YIELD node as n
RETURN count(n);
> ~ 30000 results

当我尝试过滤这些结果时,性能会急剧下降。 Neo4j已经在我的系统中耗尽了大量的内存,所以我觉得这个命令的内存占用太多,我的系统上的查询永远不会完成。 (我正在使用neo4j-shell来运行这些命令)

WITH
({start:1300542000000,end:1350543000000}) as tr,
({lon:120.0,lat:20.0}) as smin, ({lon:122.0,lat:21.0}) as smax

CALL ga.timetree.events.range(tr) YIELD node as n
CALL spatial.bbox('spatial_records', smin, smax) YIELD node as m

WITH COLLECT(n) as nn, COLLECT(m) as mm

RETURN FILTER(x in nn WHERE X in mm);

我想知道有效过滤这两个语句调用结果的最佳方法是什么。我试图使用REDUCE子句,但无法弄清楚语法。

作为一个附带问题,鉴于这是我将向我的数据库发出的最常见的查询类型,这是一种很好的方法(如使用时间树和r树引用同一组节点) )?我还没有在neo4j中找到任何支持在单个结构中索引空间和时间的工具,所以这是我当前的实现。

1 个答案:

答案 0 :(得分:2)

第一个程序返回500k个节点,收集是一个代价高昂的操作,所以是的,这将是非常重的内存。

我会从返回较少节点的内容开始,然后使用cypher而不是过程,所以在这里我将用Cypher中的远程查询过滤器替换对timetree过程的调用。

假设您的节点上有索引 timestamp属性:

CALL spatial.bbox('spatial_records', smin, smax) YIELD node as m
WITH m 
WHERE m.timestamp > 1300542000000 and m.timestamp < 1350543000000
RETURN m

我不建议删除时间树(否则我会被解雇&lt; - joke )。在某些时候查询的情况下,timetree将胜过远程查询的查询,特别是当分辨率很高(毫秒)并且你有很多非常连续的时间戳时。

否则你似乎有一个非常好的用例,如果你可以发送关于neo4j slack或私有的更多细节(christophe at graphaware dot com),这将是很好的,这可以帮助Neo4j和GraphAware可能支持更多东西通过程序(如传递节点集合并过滤掉那些不在范围内的节点或与空间平滑组合),只要它足够通用就可以了。

与此同时,当您使用开源产品时,您可以轻松创建一个程序,将特定用例的两个过程组合在一起。