我在修改cypher查询时遇到了性能问题。给定是一个原始节点,它与子节点有大量的传出关系。这些子节点都具有密钥属性。现在的目标是在源节点和子节点之间创建新节点,以对具有相同键属性值的所有子节点进行分组。可以在neo4j控制台上找到该想法的情节:http://console.neo4j.org/?id=vinntj
我将查询与spring-data-neo4j 2.2.2.RELEASE和neo4j 1.9.2嵌入一起使用。该查询的参数必须是节点标识,该查询的结果应该是修改后的根节点。
查询当前看起来像(比链接的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个节点~380s和30000个节点> 50分钟!这看起来像是对我的o(log n)比例。但我的目标是o(n)规模,并在30分钟内处理500000多个子节点。我假设该查询的CREATE UNIQUE部分导致该问题,因为对于新的组节点,它总是需要检查已经创建了哪种类的组节点。并且要检查的数量随着已经分组的子节点的数量而增长。
有人知道如何更快地获得此查询吗?或者用其他查询更快地做同样的事情?
答案 0 :(得分: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的索引。
编辑以上查询的替代方法如下,这将防止必须使用collect第二次匹配叶节点。
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
答案 1 :(得分:1)
好吧,现在我转向不对这么大量的数据使用这种密码查询。我使用遍历API实现相同的功能以提取可分组项,并使用Neo4jTemplate
创建新节点和关系。现在可以使用之前使用的密码查询将50000个项目分组为 5474ms而不是~1h 。这是一个非常大的改进。