【问题标题】:neo4j match too slowneo4j 匹配太慢
【发布时间】:2017-02-10 16:00:32
【问题描述】:

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

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

  • 案例 1(NYC 和 LA 之间不存在边): 以成本创造优势 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 毫秒才能在我的计算机上完成,对于我的应用程序来说太慢了。有更快的方法吗?

【问题讨论】:

    标签: neo4j cypher


    【解决方案1】:

    一方面,如果关系不存在,您的查询将不会按预期运行。

    MERGE 将首先尝试 MATCH 整个模式,如果没有匹配(如果关系不存在则不会匹配)然后它将创建整个模式。这意味着它将使用这些属性创建一个重复的 New York 和 Los Angeles 节点并创建它们之间的关系,而单独留下原始的 New York 和 Los Angeles 节点(而不是连接它们)。

    为避免这种情况,请在两个节点上进行 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
    

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

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

    编辑:Dave Bennett 建议参数化城市名称和基本价格是一个不错的建议,相应地更改了查询。

    【讨论】:

    • 您可能还需要参数化城市名称和价格,以便可以缓存一个查询计划,而不是为每个新的城市对和价格组合创建一个新计划。
    猜你喜欢
    • 1970-01-01
    • 2017-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多