包含混合类型的集合不能存储在属性中

Collections containing mixed types can not be stored in properties

我是 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: Collections containing mixed types can not be stored in properties.

这意味着它只允许我有一个列表:

neo4_session.run("MERGE (t:Table {name: $name, columns: $columns}) ",
     name=table['table_name'], columns=['a','b','c'])

但是,我数据库中的每个 table 节点都有不同的列名,因此我无法真正拥有属性列表...

有什么建议吗?

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

产生于:

此外,这是一种更 "graphist" 的数据建模方式。

最简单的方法是直接将每一列存储为 属性:

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)