2012-06-12 18 views
6

Tengo la sensación de que todo esto va mal. Pero de todos modos.Neo4j comprueba si existe nodo antes de crear?

Tengo una base de datos sql que tiene esencialmente una tabla denormalizada deliberadamente que he construido para hacer esta tarea más fácil para mí, así que solo puedo tomar cosas de una tabla.

Lo que tengo es una tabla de pares, algo como esto:

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

Y así sucesivamente.

Así que para mi dúo gráfico neo4j, quiero que cada ID de usuario sea un nodo, las otras cosas no son demasiado importantes, pero básicamente serán las cosas en las relaciones.

sólo quiero un nodo para cada usuario, por lo que mi sensación es que si hago algo como esto:

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

que cuando añadimos el nodo con user_id 1234, por segunda vez, se acaba de crear un nuevo nodo, pero lo que quiero es que simplemente tome este nodo en lugar de crearlo para poder agregarlo a la relación con 1080 en este caso.

Entonces, ¿cuál es la manera de hacer esto?

Respuesta

4

Utilice un índice para buscar y, si no encuentra ningún resultado, cree uno nuevo.

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

¿Este es el tipo de operación que está buscando?

+0

Eso podría funcionar. ¿Es esto más rápido o más lento o el mismo que el método get o ccreate vinculado por Andres? Parece que hacen la misma cosa de diferentes maneras, pero realmente no entiendo cómo funcionan los índices en neo4j. –

+0

Me imagino que la indexación sería más rápida, ya que la indexación generalmente está destinada a búsquedas rápidas. – Nicholas

+0

No sé si estoy leyendo los documentos incorrectamente, pero de todos modos no los consigo o no creo usar un índice? Estoy confundido. –

2

Probablemente querrá usar el UniqueNodeFactory provisto por 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

Normalice sus tablas SQL para que parezcan nodos y relaciones. Luego, con cero a la izquierda en su migración puede hacer que el rerunnable la migración por algo así como

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

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

para los nodos y ya que usted debe tener en su mesa de centro de muchos a muchos:

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

ahora que va a terminar sin duplicados y puede volver a ejecutar tanto como desee.

0

mediante consulta cero a la izquierda, puede crear un nodo único con la siguiente sintaxis,

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

al hacer una llamada REST, se puede hacer la inserción por lotes como

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

de manera similar para la creación de relaciones en una solicitud por lotes, haga lo siguiente

$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

utilice esta función: donde: ID es la clave que desea verificar si ya existe Tipo: es el tipo de nodo (la etiqueta) esta función creará el nodo y lo devolverá, luego podrá agregar más propiedades.

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