Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
01-18-2022 03:40 AM
Hi all,
So I have an Aura pro server and want to upload a block of JSON data we're generating up to it. My little Node app, whilst generating this JSON, holds it in state, so I figured it would be simple enough to use the JS driver to send that up to the server. The query works within the browser, using the same data and command, but I get:
Neo4jError: Invalid input '[': expected "+" or "-" (line 1, column 6 (offset: 5))
"WITH [object Object],[object Object], ...
by using either writeTransaction or run using the JS driver.
Is there an inherent issue with using a 'WITH' statement with the JS driver.
The statement looks like this:
const writeQuery = `WITH ${serviceMapJson} AS objects
UNWIND objects as service
call apoc.create.node([service.type],
{name:service.name, language:service.language, ... other fields listed})
yield node
return node`;
const writeResult = await session.writeTransaction((tx) => tx.run(writeQuery));
Is there a better way of doing this with static JSON? Aura seems to make it difficult to get JSON from a path since you can't upload to the server and things like pre-signed links in S3 don't work, so I went down this more direct route of passing the JSON in the query.
Also, I didn't want to have to iterate over the JSON object in the script and make several hundred individual create requests.
Any help appreciated, thanks.
p.s. Googling for 'WITH' statement Neo4j js driver is particularly problematic - 'with' being a fairly common word an' all 🙂
Solved! Go to Solution.
01-19-2022 03:53 AM
You'd be better off passing the object as a parameter in the second parameter, like this:
const writeQuery = `
UNWIND $serviceMapJson as service
call apoc.create.node([service.type],
{name:service.name, language:service.language, ... other fields listed})
yield node
return node`;
const writeResult = await session.writeTransaction((tx) => tx.run(writeQuery, { serviceMapJson }));
That way you don't need to worry about quotes, serialising/stringifying. It's also considered best practice to avoid injection when you come to processing inputs in a user-facing application and avoids re-planning the query before execution which adds a few hundred milliseconds to the query time.
One caveat you may need to account for with the JS driver is converting JavaScript integers into Neo4j integers. By default, these will be converted by the driver into floats to avoid loss, you can read more here.
If you are interested, you can learn more in the Building Neo4j Applications with Node.js course on GraphAcademy.
01-18-2022 09:27 AM
I am not familiar with the ${serviceMapJson} syntax. Should this be $serviceMapJson instead?
01-19-2022 12:25 AM
Thanks for the reply glilienfield.
That's a NodeJS variable rather than a Cypher param. I should have put above the code snippet to make that clear:
const serviceMapJson = JSON.parse(jsonString);
01-19-2022 03:53 AM
You'd be better off passing the object as a parameter in the second parameter, like this:
const writeQuery = `
UNWIND $serviceMapJson as service
call apoc.create.node([service.type],
{name:service.name, language:service.language, ... other fields listed})
yield node
return node`;
const writeResult = await session.writeTransaction((tx) => tx.run(writeQuery, { serviceMapJson }));
That way you don't need to worry about quotes, serialising/stringifying. It's also considered best practice to avoid injection when you come to processing inputs in a user-facing application and avoids re-planning the query before execution which adds a few hundred milliseconds to the query time.
One caveat you may need to account for with the JS driver is converting JavaScript integers into Neo4j integers. By default, these will be converted by the driver into floats to avoid loss, you can read more here.
If you are interested, you can learn more in the Building Neo4j Applications with Node.js course on GraphAcademy.
01-19-2022 05:49 AM
Thanks Adam, that's solved the issue. Feeding the data in as a parameter to the call rather than as part of the writeQuery worked a treat.
Much appreciated.
All the sessions of the conference are now available online