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

时间:2018-06-26 15:17:25

标签: neo4j cypher neo4j-python-driver

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

但是,数据库中的每个表节点将具有不同的列名,因此我实际上并没有属性列表...

有什么建议吗?

2 个答案:

答案 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)

产生于:

Sample data

此外,这是一种更加“摄影师”的数据建模方式。

答案 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)