Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
08-23-2022 09:46 PM
Greetings,
I'm using Node.js, Express, & Neo4j.
I have a form that passes parameters to the server and they are being passed, but 1 parameter is a single item and the other parameter contains multiple objects in an array. I'm trying to create all of these from scratch and then relate one to the many. At this point what I have works, but instead of one to many I can only create 1 node from each different parameter and relate them.
Here's my form code on the ejs page...
The items being passed are this...
datasourcename = Datasource_Model
datasourcefieldname = ['fieldnameOne', 'fieldnameTwo', 'fieldnameThree', 'fieldnameFour', 'fieldnameFive', ...]
Here is my server code...
When I submit the data, data is created in Neo4j, but it's only creating 2 nodes: 1 ds:DataSource node and 1 dsf:DataSourceField node (the first one seen in the array) and then they are related as expected.
I don't know how to get my query to create all of the expected dsf:DataSrouceField nodes.
Thank you for any help you can provide.
Solved! Go to Solution.
08-24-2022 01:10 AM - edited 08-24-2022 01:16 AM
The way I read it, it should create one DataSourceField node whose title is an array of values. Is this not the case?
Assuming datasourcefield name is an array and you want to create a node for each element, you have two options. You can either ‘unwind’ the array into rows, so each can be used to create a node, or you can use a ‘forEach’ loop.
For the unwind approach, insert between the create ‘ds’ and ‘dsf’ nodes the ‘unwind’ statement;
unwind $datasourcefieldnameParam as fieldname
then change the ‘Title’ value when creating the ‘dsf’ node to ‘fieldname’. Finally, change your relationship ‘create’ to a ‘merge’.
For the ‘forEach’ approach, you would enclose the final two create statements in a ‘forEach’ loop iterating over $datasoucrefieldnameParam. Again, you need to change the relationship ‘create’ to a ‘merge’
https://neo4j.com/docs/cypher-manual/current/clauses/foreach/
08-24-2022 01:10 AM - edited 08-24-2022 01:16 AM
The way I read it, it should create one DataSourceField node whose title is an array of values. Is this not the case?
Assuming datasourcefield name is an array and you want to create a node for each element, you have two options. You can either ‘unwind’ the array into rows, so each can be used to create a node, or you can use a ‘forEach’ loop.
For the unwind approach, insert between the create ‘ds’ and ‘dsf’ nodes the ‘unwind’ statement;
unwind $datasourcefieldnameParam as fieldname
then change the ‘Title’ value when creating the ‘dsf’ node to ‘fieldname’. Finally, change your relationship ‘create’ to a ‘merge’.
For the ‘forEach’ approach, you would enclose the final two create statements in a ‘forEach’ loop iterating over $datasoucrefieldnameParam. Again, you need to change the relationship ‘create’ to a ‘merge’
https://neo4j.com/docs/cypher-manual/current/clauses/foreach/
08-24-2022 07:55 AM
Thanks so much @glilienfield! I'm going with the Unwind version, and think I have followed your directions and the format provided in the Unwind link, but have an error, here's my query now...
`Merge (ds:DataSource {Title: $datasourcenameParam})
With ds
Unwind $datasourcefieldnameParam as fieldname
Merge (dsf:DataSourceField {Title: fieldname.Title})
Merge (ds)-[:HAS_FIELD]->(dsf)
Set ds.date = apoc.date.format(timestamp(),"ms","MM/dd/yyyy"), ds.Uid = apoc.create.uuid(), dsf.date = apoc.date.format(timestamp(),"ms","MM/dd/yyyy"), dsf.Uid = apoc.create.uuid()
Return ds,dsf`, {datasourcenameParam:datasourcename, datasourcefieldnameParam: datasourcefieldname}
And it returns this error...
Something went wrong { Neo4jError: Type mismatch: expected a map but was String("fieldnameOne")
What am I doing wrong?
08-24-2022 08:33 AM - edited 08-24-2022 08:35 AM
The value 'fieldnameOne' is one of your elements from $datasourcefieldnameParm that you are passing. After unwinding it into 'fieldname', the value of 'fieldname' for each row is a string. You are trying to access the property 'Title' from this string on line 4, when you are setting the value of 'Title.' This is the cause of the error since 'fieldname' is not a map.
Also, your pasted code has a erroneous backpack on lines 1 and 7. I assume they are not in the original code you are executing.
Note, you should move the setting of ds.date and ds.Uid to after the merge to get 'ds', as it is setting it multiple times where it is. Have a set after line 1 for the 'ds' properties and have a set after line 4 for the 'dsf' properties.
08-24-2022 09:36 AM
Ah right on thanks all around! yes, the backticks are required by the node server but not the cypher itself
08-24-2022 08:22 AM
Here we go, did a bit more tweaking (that Unwind documentation seems to want to add an extra key bit that wasn't helpful)
Merge (ds:DataSource {Title: $datasourcenameParam})
With ds
Unwind $datasourcefieldnameParam as fieldname
Merge (dsf:DataSourceField {Title: fieldname})
Merge (ds)-[:HAS_FIELD]->(dsf)
Many Thanks @glilienfield
All the sessions of the conference are now available online