neo4j比赛太慢了

时间:2017-02-10 16:00:32

标签: neo4j cypher

我有一个图表,其中节点是美国城市,边缘是城市之间的旅行成本。我有关于成本(边缘)不断进入的数据,需要快速插入边缘。 这就是我想要做的事情: 假设当前的输入数据是

"New York, New York; Los Angeles, California; 1000"

  • 案例1(纽约和洛杉矶之间没有边缘): 用成本创造优势 1000
  • 案例2a(边缘存在但成本高于1000):更换成本 用1000
  • 案例2b(存在边缘且成本低于1000):做 没什么

目前,我的密码查询如下所示:

MERGE (a:City{name:"New York, New York"})-[r:TO]->(b:City{name:"Los Angeles"})  
SET r.price = CASE WHEN (NOT exists(r.price) OR r.price>1000)THEN 1000 ELSE r.price END

这需要大约100毫秒才能在我的电脑上完成,对我的应用来说太慢了。有没有更快的方法呢?

1 个答案:

答案 0 :(得分:0)

如果关系不存在,那么您的查询将无法按照您的意图行事。

MERGE将首先尝试匹配整个模式,如果没有匹配(如果关系不存在则不存在),那么它将创建整个模式。这意味着它将使用这些属性创建一个重复的纽约和洛杉矶节点并创建它们之间的关系,只保留原始的纽约和洛杉矶节点(而不是连接它们)。

为了避免这种情况,在两个节点上进行MATCH(除非它们可能还不存在,在这种情况下使用MERGE),然后在它们之间的关系上进行MERGE。您还可以使用ON MATCH和ON CREATE子句来划分至少一个案例,从而无需测试不存在的价格:

WITH {basePrice} as basePrice
MATCH (a:City{name:{fromCity}})
MATCH (b:City{name:{toCity}})
MERGE (a)-[r:TO]->(b)
ON CREATE SET r.price = basePrice
ON MATCH SET r.price = CASE WHEN r.price > basePrice THEN basePrice ELSE r.price END

为了提高性能,您应该在标签/属性组合上有索引或唯一约束(以适用者为准)。

在索引或约束启动后,如果您仍然看到性能问题,您可能需要查询您的查询并将计划(扩展节点)添加到您的描述中,这通常可以提供其他优化方法的线索

编辑:Dave Bennett关于参数化城市名称和基本价格的建议很好,相应地改变了查询。