2012-06-12 108 views
6

我有一種感覺,我正在談論這一切都是錯誤的。但不管怎麼說。Neo4j在創建之前檢查節點是否存在?

我有一個sql數據庫,其本質上是一個有目的的denormalised表,我已經構造使這個任務更容易我,所以我可以從一個表中抓取東西。

我有什麼是對的表格,是這樣的:

user_lo | user_hi | something_else | other stuff 
1000 | 1234 | 1231251654  | 123 
1050 | 1100 | 1564654  | 45648 
1080 | 1234 | 456444894648 | 1 

等。

因此,對於我的neo4j圖形數據庫,我希望每個用戶id作爲節點,其他的東西不是太重要,但基本上會成爲關係中的東西。

我只希望爲每個用戶一個節點,所以我的感覺是,如果我做這樣的事情:

while (rs.next()) { 
    node_lo = db.createNode(); 
    node_lo.setProperty("user_id", rs.getInt(1)); 
    node_hi = db.createNode(); 
    node_hi.setProperty("user_id", rs.getInt(2)); 
} 

,當我們添加與USER_ID 1234第二次節點,它只會創造一個新的節點,但我想要的只是抓住這個節點而不是創建它,所以我可以在這種情況下將它添加到1080的關係。

那麼這樣做的方法是什麼?

回答

2

你看過嗎CREATE UNIQUE

如果你不能使用Cypher,也許你可以使用unique nodes

+0

獲得或創建工廠工作得很好,謝謝。 –

4

使用索引進行搜索,如果找不到結果,則創建一個新索引。

Index<Node> userIndex = graphDatabaseService.index().forNodes('UserNodes'); 

IndexHits<Node> userNodes = userIndex.get('id', 1234); 

if(!userNodes.hasNext()){ 
    //Create new User node 
} else { 
    Node userNode = userNodes.next(); 
} 

這是您正在尋找的操作類型嗎?

+0

這可以工作。這是更快還是更慢,還是與Andres鏈接的get或ccreate方法相同?看起來他們以不同的方式做同樣的事情,但我並不真正瞭解索引如何在neo4j中工作。 –

+0

我會想象索引會更快,因爲索引通常用於快速查找。 – Nicholas

+0

我不知道我是否閱讀錯誤的文檔,但是無論如何都沒有獲取或創建索引?我很困惑。 –

2

您可能會想要使用Neo4j提供的UniqueNodeFactory

public Node getOrCreateUserWithUniqueFactory(String username, GraphDatabaseService graphDb) 
{ 
    UniqueFactory<Node> factory = new UniqueFactory.UniqueNodeFactory(graphDb, "UserNodes") 
    { 
     @Override 
     protected void initialize(Node created, Map<String, Object> properties) 
     { 
      created.setProperty("id", properties.get("id")); 
     } 
    }; 

    return factory.getOrCreate("id", id); 
} 
1

規範化SQL表,使其看起來像節點和關係。然後在您的遷移暗號,你可以通過一些使遷移rerunnable像

start a = node:node_auto_index('id:"<PK_Value>"') 
delete a 

create a = {id: "<PK_VALUE>", etc} 

爲節點,因爲你應該在你的許多一對多中間表:

start LHS = node:node_auto_index('id:"<LHS_PK>"'), 
     RHS = node:node_auto_index('id:"<RHS_PK>"') 
create unique LHS=[:<relType> {<rel props>}]->RHS 

現在你將結束沒有重複,並可以重新運行,只要你喜歡。

0

使用暗號查詢,您可以創建一個獨特的節點使用下面的語法,

CYPHER 2.0 merge (x:node_auto_index{id:1}) 

做出REST調用的時候,可以進行批量插入像

$lsNodes[] = array(

      'method'=> 'POST', 'to'=> '/cypher', 

      'body' => array(
       'query' => 'CYPHER 2.0 merge (x:node_auto_index{id_item:{id}})', 
       'params' => array('id'=>1) 
      ), 
      'id'=>0 

     ); 

     $sData = json_encode($lsNodes); 

同樣用於創建關係批量請求,請執行以下操作:

$lsNodes[] = array(

         'method'=> 'POST', 'to'=> '/cypher', 

         'body' => array(
          'query'  => 'start a=node:node_auto_index(id={id1}), b = node:node_auto_index(id={id2}) create unique a-[:have{property:30}}]-b;', 
          'params' => array(
           'id1' => 1, 'id2'=> 2 
          ) 
         ), 
         'id' => 0 

        ); 
$sData = json_encode($lsNodes); 
1

使用此功能: 其中: ID是您要檢查的密鑰是否已存在 類型:是節點的類型(標籤) 此函數將創建節點並返回它,然後您可以添加更多屬性。

public static Node getOrCreateUserWithUniqueFactory(long ID, GraphDatabaseService graphDb, String Type) 
{ 
    UniqueFactory<Node> factory = new UniqueFactory.UniqueNodeFactory(graphDb, Type) 
    { 
     @Override 
     protected void initialize(Node created, Map<String, Object> properties) 
     { 

      created.addLabel(DynamicLabel.label(Type)); 
      created.setProperty("ID", properties.get("ID")); 
     } 
    }; 

    return factory.getOrCreate("ID", ID); 
} 
相關問題