Neo4j check if node exists before creation?

I have the feeling that I'm doing it all wrong. But anyway.

I have a sql database that has an essentially focused denormalized table that I created to facilitate this task, so I can just grab the material from one table.

I have a pairs table, something like this:

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

Etc.

So, for my db neo4j graph, I want each user id to be node, the other stuff is not too important, but it will be basic in the relationship.

I only need one node for each user, so I feel that if I do something like this:

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

That when we add a node with user_id 1234 a second time, it will just create a new node, but I want it to just grab that node instead of creating it, so that I can add it to 1080 in this case.

So what is the way to do this?

+6
source share
6 answers

Have you watched CREATE UNIQUE ?

If you cannot use Cypher, perhaps you can use unique nodes ?

+2
source

Use the index to search, and if the result is not found, create a new one.

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

Is this the type of operation you are looking for?

+4
source

You probably want to use the UniqueNodeFactory provided by 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 ); } 
+2
source

Normalize your SQL tables so that they look like nodes and relationships. Then with cypher in your migration, you can do the redirection again with something like

 start a = node:node_auto_index('id:"<PK_Value>"') delete a create a = {id: "<PK_VALUE>", etc} 

for nodes and since you should have many-to-many in your table:

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

Now you will not have duplicates and you can restart as much as you want.

+1
source

use this function: where: ID is the key you want to check if it already exists. Type: node type (label) this function will create a node and return it, then you can add additional properties.

 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 ); } 
+1
source

using a cypher request, you can create a unique node with the following syntax

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

when calling REST, you can perform a batch insert, for example

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

similarly, to create relationships in a batch request, do the following

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

Source: https://habr.com/ru/post/917896/


All Articles