2

我在修改密码查询时遇到了性能问题。Given 是一个与子节点有大量传出关系的源节点。这些子节点都有一个 key 属性。现在的目标是在源节点和子节点之间创建新节点,以将共享相同键属性值的所有子节点分组。可以在 neo4j 控制台上找到该想法的情节:http ://console.neo4j.org/?id=vinntj

我将查询与嵌入的 spring-data-neo4j 2.2.2.RELEASE 和 neo4j 1.9.2 一起使用。该查询的参数必须是节点 ID,并且该查询的结果应该是修改后的根节点。

查询当前看起来像(比链接的 neo4j 控制台复杂一点):

START root=node({0})
MATCH (root)-[r:LEAF]->(child)
SET root.__type__='my.GroupedRoot'
DELETE r
WITH child.`custom-GROUP` AS groupingKey, root AS origin, child AS leaf
CREATE UNIQUE (origin)-[:GROUP]->(group{__type__:'my.Group',key:'GROUP',value:groupingKey,origin:ID(origin)})-[:LEAF]->(leaf)
RETURN DISTINCT origin

属性 custom-GROUP 是分组依据。在 SDN 中,它由 DynamicProperties 对象表示。我将它以及创建的组节点的 groupingKey 和 origin 属性注释为索引。

对于 5000 个子节点,将它们分组大约需要 50 秒。对于 10000 个节点 ~90 秒。对于 20000 个节点 ~380 秒,对于 30000 个节点 > 50 分钟!对我来说,这看起来像一个 o(log n) 比例。但我的目标是 o(n) 规模,并在 30 分钟以下处理 500000+ 个子节点。我假设该查询的 CREATE UNIQUE 部分会导致该问题,因为对于新的组节点,它总是需要检查已经创建了哪种组节点。并且检查的数量随着已经分组的子节点的数量而增长。

有人知道如何更快地获取此查询吗?或者用其他查询更快地做同样的事情?

4

2 回答 2

1

好吧,现在我转向不对如此大量的数据使用这种密码查询。我使用遍历 API 实现了相同的功能,用于提取可分组项并Neo4jTemplate创建新节点和关系。现在 50000 个项目可以在 5474 毫秒内进行分组,而不是之前使用的密码查询约 1 小时。这是一个非常大的改进。

于 2013-08-27T07:02:42.057 回答
1

如果 CREATE UNIQUE 确实是问题,那么这将首先创建组,然后映射到它们。

START root=node(*)
MATCH (root)-[r:LEAF]->(child) 
WHERE HAS (root.key) AND root.key='root' 
WITH DISTINCT child.key AS groupingKey, root as origin
CREATE UNIQUE (origin)-[:GROUP]->(intermediate { key:groupingKey,origin:ID(origin)})
WITH groupingKey, origin, intermediate
MATCH (origin)-[r:LEAF]->(leaf)
WHERE leaf.key = groupingKey
DELETE r
CREATE (intermediate)-[:LEAF]->(leaf)
RETURN DISTINCT origin

由于某种原因,控制台不允许我查看我们任何一个查询的执行计划,所以我不确定它是否会有所帮助。

您还可以考虑对根进行索引,这样您就不必在所有节点上执行“WHERE”。您可以只检查 key=root 的索引。

编辑上述查询的替代方法如下,它将防止必须通过使用收集来第二次匹配叶节点。

START root=node(*)
MATCH (root)-[r:LEAF]->(child) 
WHERE HAS (root.key) AND root.key='root'
DELETE r 
WITH DISTINCT child.key AS groupingKey, root as origin, COLLECT(child) as children
CREATE UNIQUE (origin)-[:GROUP]->(intermediate { key:groupingKey,origin:ID(origin)})
WITH groupingKey, origin, intermediate, children
FOREACH(leaf IN children : CREATE (intermediate)-[:LEAF]->(leaf))
RETURN DISTINCT origin
于 2013-08-23T16:47:15.893 回答