代码之家  ›  专栏  ›  技术社区  ›  Elessar.perm

Neo4j循环性能

  •  1
  • Elessar.perm  · 技术社区  · 8 年前

    当我试图找出一个节点的子树大小时,neo4j只能遍历600000个节点,其中只有130个是唯一的。 这是因为周期。 看起来它适用 distinct 仅在它遍历整个图到最大深度之后。

    查询是:

    match (a1)-[o1*1..]->(a2) WHERE a1.id = '123' RETURN distinct a2
    
    1 回复  |  直到 8 年前
        1
  •  2
  •   cybersam    8 年前

    通过使用APOC过程,您可以一次迭代遍历子图“层”,同时避免多次重新处理同一节点 apoc.periodic.commit 该过程迭代地处理查询,直到返回0。

    下面是这种技术的一个示例。它:

    • 使用临时 TempNode 节点跟踪迭代之间的两个重要值,其中一个最终将包含子图中节点的假id(除了“根”节点的id,因为您的问题的查询也忽略了这一点)。
    • 假设您关心的所有节点共享同一标签, Foo ,你有一个索引 Foo(id) .这是为了加快 MATCH 并且不是严格必需的。

    步骤1:创建TempNode(使用合并,以重用现有节点(如果有)

    WITH '123' AS rootId
    MERGE (temp:TempNode)
    SET temp.allIds = [rootId], temp.layerIds = [rootId];
    

    步骤2:执行迭代(以获取所有子图节点)

    CALL apoc.periodic.commit("
      MATCH (temp:TempNode)
      UNWIND temp.layerIds AS id
      MATCH (n:Foo) WHERE n.id = id
      OPTIONAL MATCH (n)-->(next)
      WHERE NOT next.id IN temp.allIds
      WITH temp, COLLECT(DISTINCT next.id) AS layerIds
      SET temp.allIds = temp.allIds + layerIds, temp.layerIds = layerIds
      RETURN SIZE(layerIds);
    ");
    

    步骤3:使用子图ID

    MATCH (temp:TempNode)
    // ... use temp.allIds, which contains the distinct ids in the subgraph ...