2012-06-12 19 views
6

Ho la sensazione che tutto vada storto. Ma in ogni caso.Neo4j controlla se il nodo esiste prima della creazione?

Ho un database sql che ha essenzialmente una tabella denormalizzata che ho costruito per rendere questo compito più facile per me, così posso semplicemente prendere roba da una tabella.

Quello che ho è una tabella di coppie, qualcosa di simile:

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

E così via.

Quindi per il mio grafico neo4j db, voglio ogni id utente come nodo, l'altra roba non è troppo importante ma sarà fondamentalmente la sostanza nelle relazioni.

voglio solo un nodo per ogni utente, quindi la mia sensazione è che se faccio qualcosa di simile:

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)); 
} 

Che quando si aggiunge il nodo con user_id 1234 per la seconda volta, sarà solo creare un nuovo nodo, ma io quello che voglio è che accetti questo nodo invece di crearlo in modo da poterlo aggiungere alla relazione a 1080 in questo caso.

Quindi qual è il modo di fare questo?

risposta

2

Hai guardato a CREATE UNIQUE?

Se non è possibile utilizzare Cypher, è possibile utilizzare unique nodes?

+0

ottenere o creare factory ha funzionato bene, grazie. –

4

Utilizzare un indice per cercare e, se nessun risultato è stato trovato, crearne uno nuovo.

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(); 
} 

È questo il tipo di operazione che stai cercando?

+0

Potrebbe funzionare. È più veloce o più lento o uguale al metodo get o ccreate collegato da Andres? Sembra che facciano la stessa cosa in modi diversi, ma non capisco davvero come funzionano gli indici in neo4j. –

+0

Immagino che l'indicizzazione sia più veloce, in quanto l'indicizzazione di solito è pensata per una ricerca rapida. – Nicholas

+0

Non so se sto leggendo i documenti errati, ma non ottengo o creo comunque un indice? Non ho capito bene. –

2

Probabilmente vorrai utilizzare il UniqueNodeFactory fornito da Neo4j.

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

Normalizza le tabelle SQL in modo che assomiglino a nodi e relazioni. Poi, con Cypher nella migrazione è possibile effettuare la rerunnable migrazione da qualcosa come

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

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

per i nodi e dal momento che si dovrebbe avere nella vostra molti-a-molti tabella centrale:

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

ora vi ritroverete senza duplicati e riesegui quanto vuoi.

0

utilizzando interrogazione cifra, è possibile creare un nodo unico con la seguente sintassi,

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

quando si effettua una chiamata REST, si può fare l'inserimento dei lotti come

$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); 

simile per la creazione di relazioni in una richiesta batch, effettuare le seguenti operazioni

$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

utilizzare questa funzione: dove: ID è la chiave che si desidera verificare se esiste già Tipo: è il tipo del nodo (l'etichetta) questa funzione creerà il nodo e lo restituirà, quindi è possibile aggiungere ulteriori proprietà.

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); 
} 
Problemi correlati