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

时间:2019-03-07 23:37:45

标签: graph neo4j cypher

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

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

// 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

但是,当连接到每个(t)的{​​{1}}的数量很大时,我不确定此方法是否非常有效。有没有一种方法可以写查询或为数据库建立索引,以使查询时间与帐户数量成线性比例,无论连接到这些帐户节点的交易数量如何?

为了公开起见,我在neo4j community forum上发布了此问题的一个版本,但我希望此网站上的访问量增加,可以使该问题得到更多的了解。

1 个答案:

答案 0 :(得分:2)

在neo4j 3.5中,添加了新的"index-backed order by"优化。这意味着,如果创建“本机”索引(有关详细信息,请参见here),则索引将按排序顺序存储,并且在使用该索引的属性上有ORDER BY子句实际上并不需要进行任何排序。

因此,假设您已在:Transaction(timestamp)的索引中创建,就像这样:

CREATE INDEX ON :Transaction(timestamp);

然后,在neo4j 3.5+中,此查询(带有使用该索引的可选提示)在为每个Transaction查找具有最大timestamp的{​​{1}}时应避免任何排序:

Address

此查询应执行以下操作:

  1. 使用索引获取具有适当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 的所有Transaction节点(降序排列,不进行排序)。
  2. 获取与每个timestamp相关的Address节点。
  3. 对于每个不同的Transaction节点,创建所有相关Address节点的列表(降序Transaction,不进行排序),然后从列表中获得第一个。 / li>
  4. 返回每个不同的timestamp节点及其最近的相应Address节点。

该查询将根据相应的 Transaction 的数量线性扩展。如果您的用例允许,可以通过在Transactions子句中设置下限来减少适当的Transactions的数量,从而获得更快的结果。