Neo4j 在大量现有节点上优化关系创建

Neo4j 在大量现有节点上优化关系创建,neo4j,cypher,Neo4j,Cypher,我的cypher查询用于在大量节点(~1000-10000)之间创建关系,如下所示 "MATCH (startNode1),....,(startNode1000),(endNode1),..(endNode1000) WHERE ID(startNode1) = 538035 AND .. ID(startNode1000) = 538035 AND ID(endNode1) = 577 ..ID(endNode1000) = 586 CREATE (

我的cypher查询用于在大量节点(~1000-10000)之间创建关系,如下所示

    "MATCH (startNode1),....,(startNode1000),(endNode1),..(endNode1000)
     WHERE ID(startNode1) = 538035 AND .. ID(startNode1000) = 538035 AND ID(endNode1) = 577 ..ID(endNode1000) = 586 
     CREATE 
     (startNode1)-[r1:`ParameterValue`{Name: "Phi"}]->(endNode1),
     (startNode2)-[r2:`ParameterValue`{Type: "block"}]->(endNode2),..
     (startNode1000)-[r100:`ParameterValue`{FontAngle: "auto"}]->(endNode1000)
     RETURN ID(r1), ID(r2), ..... ID(r1000)"
我正在使用官方的java neo4j bolt驱动程序运行cypher查询,平均而言,上述cypher命令需要15秒,这不适合我的应用程序

我的问题是:

  • 是否有任何明显的优化我错过了捆绑我的 这么问
  • 一般来说,循环是一种好的做法吗 在节点上创建关系,而不是绑定它们

  • 我是一个新手,所以任何建议都是非常欢迎的。谢谢

    您实际上可以使用cypher创建关系

    MATCH (u:User {username:'admin'}), (r:Role {name:'ROLE_WEB_USER'})
    CREATE (u)-[:HAS_ROLE]->(r)
    
    这只是一个例子,我们有一个用户节点,我们正在创建一个与角色的关系

    这里是文档的链接

    我不认为上述方法是正确的

    通过这种方式捆绑我的cypher查询,是否有任何明显的优化我遗漏了

    对。所讨论的查询使得查询优化器和执行引擎的工作极其困难。如果您转到web浏览器并使用运行查询计划,它将向您显示此查询计划需要大量元组,而这不是引擎所要处理的

    一般来说,在节点上循环以创建关系比绑定它们好吗

    循环是一个好的方向。事实上,您可以进行以下几种优化:

  • [startNode,endNode,relationshipProperties]
    三元组的集合作为单个参数传递给驱动程序及其应用程序

  • 使用
    SET relationship\u variable=map\u variable
    初始化关系的属性

  • 或者,您可能希望使用该方法在列表中返回结果ID,但这通常不是必需的,因为驱动程序会返回一个iterable结果

  • 此查询包含以下技巧:

    UNWIND $rels AS rel
    WITH
      rel[0] AS startNodeId,
      rel[1] AS endNodeId, 
      rel[2] AS relationshipProperties
    MATCH (startNode:SomeLabel), (endNode:SomeLabel)
    WHERE ID(startNode) = startNodeId
      AND ID(endNode) = endNodeId
    CREATE (startNode)-[r:`ParameterValue`]->(endNode1)
    SET r = relationshipProperties
    WITH collect(ID(r)) AS relationshipIds
    RETURN relationshipIds
    
    在客户端,您应该使用传递参数。只需一个带有
    rels
    单键和三个元素列表的映射。您可以使用一个好的收藏库,例如番石榴,以简洁的方式表达这一点:


    然后您可以将这些值引用为
    rel.startNode
    rel.endNode
    rel.relationshipProperties
    。这使查询更具可读性,更易于维护,但通常不值得这么麻烦。

    非常感谢!这是一个很好的信息,我会在试用后回复您有关性能的信息。在实施解决方案后更新。我能够将建立关系的时间从15秒减少到0.2秒!再次感谢您提供的解决方案和其他建议。
    Map<String, Object> parameters =
      ImmutableMap.of("rels",
        ImmutableList.of(
          ImmutableList.of(1, 2, ImmutableMap.of("prop1", "value1", "prop2", false)),
          ImmutableList.of(3, 4, ImmutableMap.of(...)),
        ...
      )
    );
    StatementRunner.run("UNWIND ...", parameters);
    
    ImmutableMap.of("startNode", 1, "endNode", 2, "relationshipProperties", ImmutableMap.of("prop1", "value1", "prop2", true))