2017-02-15 90 views
0

我試圖用「id」的獨特屬性創建TEST類型的唯一節點。Neo4j graph.index()。forNodes找不到節點

但是,forNodes()方法沒有檢測到重複項,是否有更好的方法只使用Java API,爲什麼以下方法不起作用?

public class Neo4jTest 
{ 
    public static void main(String args[]) 
    { 
     GraphDatabaseService graph = new TestGraphDatabaseFactory().newImpermanentDatabase(); 

     Label testLabel = new Label() 
     { 
      @Override 
      public String name() 
      { 
       return "TEST"; 
      } 
     }; 

     try (Transaction tx = graph.beginTx()) 
     { 
      graph.schema() 
        .constraintFor(testLabel) 
        .assertPropertyIsUnique("id") 
        .create(); 
      tx.success(); 
     } 

     try (Transaction tx = graph.beginTx()) 
     { 
      int k = 99; 
      for (int i = 0; i < 4; i++) 
      { 
       System.out.println("indexing... i="+i); 
       Index<Node> testIndex = graph.index().forNodes(testLabel.name()); 
       IndexHits<Node> testIterator = testIndex.get("id", k); 

       if (!testIterator.hasNext()) 
       { 
        System.out.println("creating node... i="+i); 
        Node testNode = graph.createNode(testLabel); 
        testNode.setProperty("id", k); 
        tx.success(); 
       } 
      } 
     } 
    } 
} 

上述返回:

indexing... i=0 
creating node... i=0 
indexing... i=1 
creating node... i=1 
Exception in thread "main" org.neo4j.graphdb.ConstraintViolationException: Node 0 already exists with label TEST and property "id"=[99] 

不應上述檢測i = 1時,有已存在使用ID = 99的節點???

編輯:同樣的錯誤也可在不同的交易..

public class Neo4jTest 
{ 

    public static void main(String args[]) 
    { 
     GraphDatabaseService graph = new TestGraphDatabaseFactory().newImpermanentDatabase(); 

     Label testLabel = new Label() 
     { 
      @Override 
      public String name() 
      { 
       return "TEST"; 
      } 
     }; 

     try (Transaction tx = graph.beginTx()) 
     { 
      graph.schema() 
        .constraintFor(testLabel) 
        .assertPropertyIsUnique("id") 
        .create(); 
      tx.success(); 
     } 

     int k = 99; 

     try (Transaction tx = graph.beginTx()) 
     { 
      System.out.println("indexing... i=" + 0); 
      Index<Node> testIndex = graph.index().forNodes(testLabel.name()); 
      IndexHits<Node> testIterator = testIndex.get("id", k); 

      if (!testIterator.hasNext()) 
      { 
       System.out.println("creating node... i=" + 0); 
       Node testNode = graph.createNode(testLabel); 
       testNode.setProperty("id", k); 

      } 
      tx.success(); 
     } 

     try (Transaction tx = graph.beginTx()) 
     { 
      System.out.println("indexing... i=" + 1); 
      Index<Node> testIndex = graph.index().forNodes(testLabel.name()); 
      IndexHits<Node> testIterator = testIndex.get("id", k); 

      if (!testIterator.hasNext()) 
      { 
       System.out.println("creating node... i=" + 1); 
       Node testNode = graph.createNode(testLabel); 
       testNode.setProperty("id", k); 
      } 
      tx.success(); 
     } 
    } 
} 

回答

0

,你發現真正的問題是,testIterator是返回false時,它應返回true。當我== 1的迭代器應該已經返回!真正的,因爲它已經有一個沒有進一步插入應該發生。

但它沒有按照設計工作,它繼續插入,你會得到一個異常,因爲它應該是。該圖正在識別違反唯一性。

什麼你不知道,如果迭代器被未經事務被提交

if (!testIterator.hasNext()) 
{ 
... 
} 

注意,從0到1的節點會不涉及任何獨特性後更新緩存的。這是iterator失敗的地方:沒有更新

+0

!testIterator.hasNext()在引發異常之前發生2次,查看打印輸出,tx提交給i> = 0,實際上!testIterator.hasNext()總是失敗,但爲什麼? –

+0

這是新的信息。但是,如果你看看代碼插入只發生在if(!iterator.hasNext())內部,所以它似乎只會發生一次,當我== 0之後,下一個迭代器應該有下一個)== true。如果你想簡化的東西只是擺脫循環和插入,提交,再次插入,你應該有例外 – efekctive

+0

你可以改述你的整個答案和評論?如果它是Neo中的一個錯誤,那麼聲明如果不發佈插入的代碼,我希望沒有例外。 –