按日期获取连接到单个帐户节点的许多事务节点中的最新数据的有效方法



我有大量代表帐户的节点,我们可以将其标记为(a :Account)。每个(:Account)都可能连接数万个(t :Transaction)节点,每个节点代表涉及该帐户的交易的数据。

(:Transaction)节点具有date属性。给定一个查询日期,对于查询日期之前或当天发生的每个(a :Account),获取最新(:Transaction)节点的最有效方法是什么?这可能是一种方法:

// run for all address nodes
match (a :Address)
with distinct a
optional match (a)-->(t :Transaction)
where t.timestamp <= date("2014-03-07")
with a, t
where t.date = max(t.date)
return a, t

但是,当连接到每个(a)(t)数量变得非常大时,我不确定这种方法是否非常有效。有没有办法编写查询或索引数据库,以便查询时间与帐户数量线性缩放,而不管连接到这些帐户节点的事务数量如何?

为了披露,我在neo4j社区论坛上发布了这个问题的一个版本,但我希望这个网站上的更大流量会给这个问题更多的曝光率。

在 neo4j 3.5 中,添加了新的"索引支持的排序依据"优化。这意味着,如果您创建一个"本机"索引(有关详细信息,请参阅此处),则该索引将按排序顺序存储,并且使用该索引的属性上的ORDER BY子句实际上不必执行任何排序。

因此,假设您已经在索引中创建了:Transaction(timestamp),如下所示:

CREATE INDEX ON :Transaction(timestamp);

然后,在 Neo4j 3.5+ 中,此查询(带有使用该索引的可选提示)在查找每个Address具有最大timestampTransaction时应避免任何排序:

MATCH (a:Address)-->(t:Transaction)
USING INDEX t:Transaction(timestamp)
WHERE t.timestamp <= date("2014-03-07")
WITH a, t
ORDER BY t.timestamp DESC
RETURN a, COLLECT(t)[0] AS transaction

此查询应执行以下操作:

  1. 使用该索引获取具有适当timestamp的所有Transaction节点(按降序排列,不进行排序)。
  2. 获取与每个Transaction相关的Address节点。
  3. 对于每个不同的Address节点,创建一个所有相关Transaction节点的列表(按降timestamp顺序排列,不进行排序),并从列表中获取第一个节点。
  4. 返回每个不同的Address节点及其最新的相应Transaction节点。

此查询将随相应Transactions的数量线性缩放。如果您的用例允许,您可以通过在WHERE子句中设置下限来减少适当Transactions的数量,从而更快地获得结果。

最新更新