2014-05-22 63 views
1

我爲我的所有關係分配一個臨時屬性,但它需要大量的時間來處理大約1,900個關係。我只想通過這樣做獲得更好的表現。如何使Neo4j遍歷更快?

TraversalDescription tempTraversal = this.database.traversalDescription() 
    .depthFirst() 
    .uniqueness(Uniqueness.RELATIONSHIP_GLOBAL); 
    String uuidString = "flw-"+uuid.toString(); 
    Transaction tx = database.beginTx(); 
    try { 
     for(Relationship r : tempTraversal.traverse(this.nSource) 
      .relationships()){ 
      if (r.hasProperty("weight")) 
       r.setProperty(uuidString,r.getProperty("weight")); 
     } 
     tx.success(); 
    } catch (Exception e) { 
     System.err.println("assingTempProperty: " + e); 
     tx.failure(); 
    } finally { 
     tx.close(); 
    } 

是否有更好的解決方案呢?

+0

有多大總共的圖形?你沒有指定任何directons或rel-types?你實際上是否計算了從遍歷器返回的rels數量?你最初想做什麼? –

+0

我只想爲圖中的所有關係設置一個屬性,並設置一個臨時值。有1900個關係,400個節點。還有,我已經數過了,而且遍歷器表現不錯。這是MaxFlow算法的預處理。 –

+0

這應該是即時的。有些事情是真的錯了。 「很多時間」是什麼意思? –

回答

1

好吧,我看着它,學到了一些東西。

如果你有一個稀疏連接的圖並應用關係唯一性,你必須探索非常長的路徑才能真正找到圖中所有的唯一關係,所以你必須前後迂迴,直到找到最後一個全球唯一的關係。

你會沿着一條路徑探索整個圖。

爲了將其編入數字,我生成了一個包含10%連接節點的400個節點的圖。

您最終路徑長度爲:15845,探索1 288 374個路徑。

這裏是我使用的代碼:

@Test 
public void testTraversal() throws Exception { 
    GraphDatabaseService db = new TestGraphDatabaseFactory().newImpermanentDatabase(); 
    List<Node> nodes = new ArrayList<>(); 
    int count=0; 
    long now = System.currentTimeMillis(); 
    try (Transaction tx = db.beginTx()) { 
     for (int i=0;i<400;i++) { 
      nodes.add(db.createNode()); 
     } 
     DynamicRelationshipType knows = DynamicRelationshipType.withName("KNOWS"); 
     for (Node node1 : nodes) { 
      for (Node node2 : nodes) { 
       double random = Math.random(); 
       if (random < 0.1 && node1 != node2) { 
        node1.createRelationshipTo(node2, knows).setProperty("weight",random); 
        count++; 
       } 
      } 
     } 
     tx.success(); 
    } 
    System.out.println("generated rel-count = " + count+" time "+(System.currentTimeMillis()-now)+" ms"); 

    now = System.currentTimeMillis(); 
    String uuidString = "flw-"+ now; 
    count=0; 
    try (Transaction tx = db.beginTx()) { 
     for (Relationship r : GlobalGraphOperations.at(db).getAllRelationships()) { 
      if (r.hasProperty("weight")) 
       r.setProperty(uuidString, r.getProperty("weight")); 
      count++; 
     } 
     tx.success(); 
    } 
    System.out.println("global graph ops rel-count = " + count+" time "+(System.currentTimeMillis()-now)+" ms"); 

    final AtomicInteger pathLenght=new AtomicInteger(); 
    final AtomicInteger pathCount=new AtomicInteger(); 
    TraversalDescription tempTraversal = db.traversalDescription() 
      .depthFirst() 
      .uniqueness(new UniquenessFactory() { 
          @Override 
          public UniquenessFilter create(Object optionalParameter) { 
           return new UniquenessFilter() { 
            Set<Relationship> rels = new HashSet<Relationship>(100000); 
            @Override 
            public boolean checkFirst(TraversalBranch branch) { 
             pathCount.incrementAndGet(); 
             pathLenght.set(Math.max(pathLenght.get(),branch.length())); 
             return rels.add(branch.lastRelationship()); 
            } 

            @Override 
            public boolean check(TraversalBranch branch) { 
             pathCount.incrementAndGet(); 
             pathLenght.set(Math.max(pathLenght.get(),branch.length())); 
             return rels.add(branch.lastRelationship()); 
            } 
           }; 
          } 
         } 
    ); 
    now = System.currentTimeMillis(); 
    Transaction tx = db.beginTx(); 
    count=0; 
    try { 
     for(Relationship r : tempTraversal.traverse(nodes.get(0)) 
       .relationships()){ 
      if (r.hasProperty("weight")) 
       r.setProperty(uuidString,r.getProperty("weight")); 
      count++; 
     } 
     tx.success(); 
    } catch (Exception e) { 
     System.err.println("assingTempProperty: " + e); 
     tx.failure(); 
    } finally { 
     tx.close(); 
    } 
    System.out.println("rel-count = " + count+" time "+(System.currentTimeMillis()-now)+" ms pathlength "+pathLenght.get()+" pathCount "+pathCount.get()); 
} 
+0

謝謝,通過這段代碼我學到了很多東西。問題在於有人在此方法之前啓動線程(不知道爲什麼),並導致一團糟。 –