Reputation: 991
can't find whether this has been asked before or not, so bear with me.
I'm just starting to use Neo4j with a nodejs backend and the neo4j-driver
driver. I wonder if it's possible to create a node with several properties without enumerating each one in the second argument to the session.run
method.
app.post("/signup", function(req, res) {
var user = req.body; //{userId: "johnsmith", email: "[email protected]", ...}
session.run("CREATE (u:User {u}) RETURN u", user).then(function(response) {
/*do stuff with newly created user*/
}, function() {
//handle error
});
});
Currently, this yields the following error: {code: 'Neo.ClientError.Statement.ParameterMissing', message: 'Expected a parameter named u' }
, and if I change the above to:
app.post("/signup", function(req, res) {
var user = req.body; //{userId: "johnsmith", email: "[email protected]", ...}
session.run("CREATE (u:User {u}) RETURN u", {u: user}).then(function(response) {
/*do stuff with newly created user*/
}, function() {
//handle error
});
});
then the error reads: { code: 'Neo.ClientError.Statement.TypeError', message: 'Property values can only be of primitive types or arrays thereof' }
.
This doesn't make much sense to me, given that the refcard clearly states you can create a node using a map, like so: CREATE (n {map})
; so I must obviously be getting something wrong. I hope I don't have to enumerate all a user's properties like so:
session.run("CREATE (u:User {userId: {u.userId}, email: {u.email}, ...}) RETURN u", {u: user}).then(/*...*/)
Thanks in advance
Upvotes: 4
Views: 1495
Reputation: 66989
Neo4j only supports storing specific kinds of data structures to a property. To quote from the Cypher Refcard:
Neo4j properties can be strings, numbers, booleans or arrays thereof.
And, to be more exact, in order for an array (or "collection") to be stored as a property value, all its elements must be of the same primitive type.
The answer from @stdob-- provides one possible simple workaround to this (but it stringifies all arrays, even ones that can be stored without conversion).
NOTE: The refacrd needs to be a bit more clear. Nested maps are supported, in general. For instance, you can freely pass in JSON data as Cypher query parameters. However, maps containing nested maps are NOT supported for storing as property values.
Upvotes: 2
Reputation: 29172
For example:
app.post("/signup", function(req, res) {
var params = {};
//{userId: "johnsmith", email: "[email protected]", ...}
Object.keys(req.body).forEach( function(k) {
var value = req.body[k];
if (!isPrimitive(val)) value = JSON.stringify(value);
params[k] = value;
});
session.run("CREATE (u:User) SET u = {user} RETURN u", {user: params})
.then(function(response) {
// do stuff with newly created user
}, function() {
// handle error
});
});
Where isPrimitive
an abstract function that checks whether a variable is a primitive.
Upvotes: 2