1

I'm currently iterating over an array where each index contains two nodes and a relationship (Part_1 -> Part_2), and I'm using the Neo4jTemplate.save() method to persist it into the database. However, some indexes have repeated nodes that will have relationships with other nodes (Part_2 -> Part_3). My version currently creates a new node and relationship every time instead of merging if a node already exists.

I read this post, but I don't understand how to implement it so that two of the same nodes will have the same ID. My current code works like this:

  1. Create two nodes
  2. Create their relationship
  3. Add relashionship to the node
  4. Persist it using Neo4jTemplate.save()

What do I need to change to MERGE instead of CREATE? Do I need to do a check before I persist or is there a way to check while persisting in SDN 4?

EDIT:

I've decided to use the Neo4jTemplate.query() method to write Cyper queries, however I don't know how to create the parameters correctly for merging multiple nodes. I can create a MERGE statement correctly like this for one node:

Map<String, Object> params = new HashMap<String, Object>();
Map<String, Object> node = new HashMap<String, Object>();

node.put("name", "Part_1");
params.put("props", node_1);
String query = "MERGE( n1:Part {name:{props}.name} )";

template.query(query, params);

My goal is to call merge on two nodes and then call merge again to create the relationship in one statement. My code right now looks like this:

Map<String, Object> params = new HashMap<String, Object>();
List<Map<String, Object>> maps;
Map<String, Object> node1 = new HashMap<String, Object>();
Map<String, Object> node2 = new HashMap<String, Object>();

node1.put("name1", "Part_1");
node2.put("name2", "Part_2");
maps = Arrays.asList(node_1, node_2)

params.put("props", maps);
String query = "MERGE( n1:Part {name:{props}.name1} )
MERGE( n2:Part {name:{props}.name2 )
MERGE(n1)-[:CREATED]->(n2)";

template.query(query, params);

All the examples I've seen so far with multiple nodes in the parameters simply just iterate through the whole thing when called. I haven't found any examples that have parameters where you can specify the certain node in it that you're referring to. How do I create a parameter where I refer to a certain node? Thanks in advance!

Community
  • 1
  • 1
jlam1618
  • 25
  • 6

1 Answers1

3

It's hard to suggest what to change without seeing your code, but it sounds like you're saving new entity instances every time.

The entity passed to Neo4jTemplate.save(entity) should be updated with an ID once it's been written to the database. SDN will try to update nodes that already have an ID so I'd suggest re-using entity instances instead of creating new ones.

If you don't want to manage these entities yourself, you could attempt to load entities in step 1 and then only create them if they don't already exist.

ATG
  • 1,679
  • 14
  • 25
  • The problem with loading them all at once is that I'll have to keep track of whats been created already and and what hasn't and then take into account their relationships. I want neo4j to do all that work since it does have an implementation (MERGE) that can do that. Do you have any suggestions on my new approach? Using Cypher to do this is quite easy, however I've been struggling with creating the parameters correctly. – jlam1618 Aug 14 '15 at 18:58
  • Sorry for the delayed reply. Have you got this working yet? If not I'll look into it for you a bit later on. – ATG Aug 18 '15 at 15:41
  • Yes, I did get it working. It took me a while to format the parameters correctly, but I'm using the Neo4jTemplate.query() method to persist my data now. Thank you though! – jlam1618 Aug 19 '15 at 16:26