我是Neo4j的新手,我正在尝试创建一个像这样的节点:
neo4_session.run("MERGE (t:Table {name: $name, columns: $columns}) ",
name=table['table_name'], columns=[{'colname':'a'},{'colname':'b'},{'colname':'c'}])
Neo4j告诉我:
neo4j.exceptions.CypherTypeError:包含混合类型的集合 不能存储在属性中。
这意味着它只允许我列出一个清单:
neo4_session.run("MERGE (t:Table {name: $name, columns: $columns}) ",
name=table['table_name'], columns=['a','b','c'])
但是,数据库中的每个表节点将具有不同的列名,因此我实际上并没有属性列表...
有什么建议吗?
答案 0 :(得分:1)
我认为您应该考虑使用:Column
节点标签而不是:Table
节点中的列列表。
这样,您可以像这样对图形进行建模:
CREATE (table:Table {name : 'Table 1'})
CREATE (columnA:Column {colname : 'a'})
CREATE (columnB:Column {colname : 'b', otherProp: 'Other value'})
CREATE (columnC:Column {colname : 'c'})
CREATE (table)-[:CONTAINS]->(columnA)
CREATE (table)-[:CONTAINS]->(columnB)
CREATE (table)-[:CONTAINS]->(columnC)
产生于:
此外,这是一种更加“摄影师”的数据建模方式。
答案 1 :(得分:1)
最简单的方法是将每个列直接存储为属性:
CREATE (table:Table {name: 'Table 1', colName1: 'a', colName2: 'b', colName3: 'c'})
并且,如果由于某种原因需要按列顺序访问列,则可以有一个数组,例如colNames
,用于存储排序的列名:
CREATE (table:Table {
name : 'Table 1',
colName1: 'a', colName2: 'b', colName3: 'c',
colNames: ['colName1', 'colName2', 'colName3']
})
另外,请参见this related question和我在回答中建议的第三种方法。
[更新]
如@Tezra所示,上面的CREATE
子句可以改进为仅接受一个参数,该参数的值是由代码动态生成的映射。例如,如果将其作为$data
参数传递:
{
name : 'Table 1',
colName1: 'a', colName2: 'b', colName3: 'c',
colNames: ['colName1', 'colName2', 'colName3']
}
然后,这个CREATE
子句将获得与我之前的子句相同的结果:
CREATE (table:Table $data)