我有很多代表帐户的节点,我们可以将其标记为(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上发布了此问题的一个版本,但我希望此网站上的访问量增加,可以使该问题得到更多的了解。
答案 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
此查询应执行以下操作:
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
节点(降序排列,不进行排序)。timestamp
相关的Address
节点。Transaction
节点,创建所有相关Address
节点的列表(降序Transaction
,不进行排序),然后从列表中获得第一个。 / li>
timestamp
节点及其最近的相应Address
节点。该查询将根据相应的 Transaction
的数量线性扩展。如果您的用例允许,可以通过在Transactions
子句中设置下限来减少适当的Transactions
的数量,从而获得更快的结果。