Creating parent/child heirachy from a list

This is my query:

WITH [
	{id: 1, name: "Gold"}, 
	{id: 2, name: "Banking"},
	{id: 3, name: "Canada"},
	{id: 4, name: "T.BMO", parentId: 2},
	{id: 5, name: "Opinion"},
	{id: 6, name: "BC", parentId: 3}
] AS tags
FOREACH (tag in tags | 
	CREATE (t:Tag) SET t=tag
	CREATE (t)-[:CHILD]->(:Tag{id:tag.parentId})
)

I expected it to add parent/child relationships where the parent id property exists, but it actually creates a number of empty records and creates relationships to them. Can someone fill the gap in my understanding of what's going on. Thanks.

When you do this:

	CREATE (t)-[:CHILD]->(:Tag{id:tag.parentId})

You're creating the entire pattern. Only the t is bound to a previously matched node. There is nothing in this CREATE that says to first try to MATCH to the :Tag node at the other end, it's a CREATE clause, so it will create it the :Tag node at the other side with the given id.

Try something like this instead:

UNWIND [
	{id: 1, name: "Gold"}, 
	{id: 2, name: "Banking"},
	{id: 3, name: "Canada"},
	{id: 4, name: "T.BMO", parentId: 2},
	{id: 5, name: "Opinion"},
	{id: 6, name: "BC", parentId: 3}
] AS tag
CREATE (t:Tag) 
SET t=tag
WITH t, tag.parentId as parentId
MATCH (parent:Tag {id:parentId})
CREATE (t)-[:CHILD]->(parent)