neo4j比赛太慢了

neo4j比赛太慢了,neo4j,cypher,Neo4j,Cypher,我有一个图,其中节点是美国城市,边是城市之间的旅行成本。我有关于成本(边缘)的数据,需要快速插入边缘。 以下是我想做的: 假设当前传入的数据是 “纽约,纽约;加利福尼亚州洛杉矶;1000” 案例1(纽约和洛杉矶之间不存在边缘): 以成本创造优势 一千 案例2a(存在边缘但成本高于1000):更换成本 一千 案例2b(存在边缘且成本低于1000):Do 没什么 目前,我的密码查询如下所示: MERGE (a:City{name:"New York, New York"})-[r:TO]->

我有一个图,其中节点是美国城市,边是城市之间的旅行成本。我有关于成本(边缘)的数据,需要快速插入边缘。 以下是我想做的: 假设当前传入的数据是

“纽约,纽约;加利福尼亚州洛杉矶;1000”

  • 案例1(纽约和洛杉矶之间不存在边缘): 以成本创造优势 一千
  • 案例2a(存在边缘但成本高于1000):更换成本 一千
  • 案例2b(存在边缘且成本低于1000):Do 没什么
目前,我的密码查询如下所示:

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毫秒,对于我的应用程序来说速度太慢。有没有更快的方法呢?

首先,如果关系不存在,您的查询将无法按照您的意愿进行

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建议将城市名称和基准价格参数化,这是一个很好的建议,因此相应地修改了查询。

您可能还希望将城市名称和价格参数化,以便缓存一个查询计划,而不是为每个新的城市对和价格组合创建一个新计划。