Creating Relationships in Neo4j Without Recreating Nodes

58 Views Asked by At

I'm currently working on a project using Neo4j, and I'm facing a challenge related to creating relationships without recreating nodes. Here's a brief overview of the scenario: want to establish relationships between an existing user, a new post, and multiple categories (already exists).

I aim to establish relationships between an existing user, a newly created post, and multiple pre-existing categories. However, the issue is that, instead of creating relationships only, multiple posts are being generated.

Below is the current Cypher query:

MATCH (user:User {username: 'your_username'})
MATCH (categories:Category)
WHERE ID(categories) IN [1, 2, 3]

// Create a new post node (you can adjust this part based on your post structure)
CREATE (post:TPost {title: 'Post Title', content: 'Post Content', createdAt: timestamp()})

// Create relationships between the user and the post
CREATE (user)-[:POSTED]->(post)

WITH post, COLLECT(categories) AS categoryList

// this part should create relationships only 
FOREACH (category IN categoryList | 
    CREATE (post)-[:BELONGS_TO]->(category) 
);

enter image description here

2

There are 2 best solutions below

1
B A.J Amar On BEST ANSWER

Firstly, I want to express my gratitude for your assistance (@Finbar Good). Your solution was quite close to what I needed. However, there was a little issue – instead of creating multiple posts, it was generating new category nodes. To fix this, I implemented a forEach loop, and it resolved the problem.

MATCH (user:User {username: 'user_name'})
CREATE (post:TPost {title: 'Post Title', content: 'Post Content', createdAt: timestamp()})
CREATE (user)-[:POSTED]->(post)
WITH post
MATCH (categories:Category)
WHERE id(categories) IN [12, 7, 9]
WITH post, collect(categories) as cats
FOREACH (c IN cats | CREATE (post)-[:BELONGS_TO]->(c))

RETURN *

enter image description here

0
Finbar Good On

Your second MATCH returns 3 Category nodes, so the table that is the input to your CREATE (:TPost) clause has 3 rows, which means the CREATE happens 3 times, creating 3 posts.

Move the CREATE (:TPost) to before fetching the 3 Category nodes and it will only execute once (assuming there is only one match for the User):

MATCH (user:User {username: 'your_username'})
CREATE (post:TPost {title: 'Post Title', content: 'Post Content', createdAt: timestamp()})
CREATE (user)-[:POSTED]->(post)
WITH post
MATCH (category:Category)
WHERE id(category) IN [1, 2, 3]
CREATE (post)-[:BELONGS_TO]->(category);