1

我是 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'])

但是,我的数据库中的每个表节点都会有不同的列名,所以我真的不能有一个属性列表......

有什么建议吗?

4

2 回答 2

2

我认为您应该考虑使用: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)

结果:

样本数据

此外,这是一种更“图形化”的数据建模方式。

于 2018-06-26T16:04:26.357 回答
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']
})

另外,请参阅这个相关问题和我在回答中建议的第三种方法。

[更新]

正如@Tezra 所指出的,上述CREATE子句可以被细化为只接受一个参数,其值是由您的代码动态生成的映射。例如,如果这是作为$data参数传递的:

{
  name : 'Table 1',
  colName1: 'a', colName2: 'b', colName3: 'c',
  colNames: ['colName1', 'colName2', 'colName3']
}

那么这个CREATE子句将得到与我之前的子句相同的结果:

CREATE (table:Table $data)
于 2018-06-26T18:48:29.037 回答