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

How can I efficiently filter results of multiple procedure calls in Neo4j

我设置了一个 GraphAware 时间树和空间 r 树来引用图中的大量节点。我正在尝试按时间和 space.

搜索这些记录

我个人可以在大约 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 中找到任何其他支持在单个结构中索引 space 和时间的工具,所以这是我当前的实现。

第一个过程 returns 你有 500k 个节点,收集是一项代价高昂的操作,所以是的,这会占用大量内存。

我会从returns你较少的节点开始,然后使用密码而不是过程,所以在这里我会用密码中的远程查询过滤器替换对时间树过程的调用。

假设您的节点上有一个 indexed timestamp 属性 :

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

我不建议删除时间树(否则我会被解雇 <- 笑话)。在某些时间查询情况下,时间树会优于范围查询的查询,尤其是当分辨率很高(毫秒)并且您有很多非常连续的时间戳时。

否则你似乎有一个很好的用例,如果你能发送更多关于 neo4j slack 的细节或私下(graphaware dot com 的 christophe),这会很好,这可能有助于 Neo4j 和 GraphAware 支持更多通过程序(例如传递节点集合并过滤掉那些不在范围内的节点或与空间的平滑组合)以更好的方式进行填充,只要它足够通用即可。

同时,由于您使用的是开源产品,因此您可以轻松地创建一个过程,将两个过程结合起来用于您的特定用例。