无法确定是否曾经问过这个问题,所以请耐心等待
我刚开始使用带有nodejs后端的Neo4j和neo4j-driver
驱动程序。我想知道是否有可能创建一个具有多个属性的节点,而不会在session.run
方法的第二个参数中枚举每个属性。
app.post("/signup", function(req, res) {
var user = req.body; //{userId: "johnsmith", email: "john@smith.com", ...}
session.run("CREATE (u:User {u}) RETURN u", user).then(function(response) {
/*do stuff with newly created user*/
}, function() {
//handle error
});
});
目前,这会产生以下错误:{code: 'Neo.ClientError.Statement.ParameterMissing', message: 'Expected a parameter named u' }
,如果我将上述内容更改为:
app.post("/signup", function(req, res) {
var user = req.body; //{userId: "johnsmith", email: "john@smith.com", ...}
session.run("CREATE (u:User {u}) RETURN u", {u: user}).then(function(response) {
/*do stuff with newly created user*/
}, function() {
//handle error
});
});
然后错误显示为:{ code: 'Neo.ClientError.Statement.TypeError', message: 'Property values can only be of primitive types or arrays thereof' }
。
这对我来说没有多大意义,因为the refcard明确指出您可以使用地图创建节点,如下所示:CREATE (n {map})
;所以我显然必须犯错。我希望我不必枚举所有用户的属性,如下所示:
session.run("CREATE (u:User {userId: {u.userId}, email: {u.email}, ...}) RETURN u", {u: user}).then(/*...*/)
提前致谢
答案 0 :(得分:2)
例如:
app.post("/signup", function(req, res) {
var params = {};
//{userId: "johnsmith", email: "john@smith.com", ...}
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
});
});
其中isPrimitive
是一个抽象函数,用于检查变量是否为基元。
答案 1 :(得分:2)
Neo4j仅支持将特定种类的数据结构存储到属性中。引用Cypher Refcard:
Neo4j属性可以是字符串,数字,布尔值或其数组。
而且,更确切地说,为了将数组(或"集合")存储为属性值,其所有元素必须是相同原语类型。
来自@ stdob--的答案为此提供了一种可能的简单解决方法(但它将所有数组进行字符串化,甚至可以存储而无需转换的数组。)
注意:refacrd需要更清晰一些。通常,支持嵌套地图 。例如,您可以将JSON数据作为Cypher查询参数自由传递。但是,不支持将包含嵌套映射的映射存储为属性值。