我有标签 TypeA 的节点,它有一个字符串属性 propA。propA 是一个字符串 JSON,可以使用 apoc.convert.fromJsonMap() 转换为映射。
我想创建 TypeB 的新节点,其属性为 propA,并在两个节点之间建立关系。我已成功运行以下查询:
MATCH (n:TypeA)
WITH apoc.convert.fromJsonMap(n.propA) AS values,n limit 1
MERGE (v:TypeB)
SET v=values
WITH n,v
MERGE (v)-[:RELATION_TYPE]->(n)
RETURN v,n;
但是,当我使用以下 apoc.periodic.iterate 来转换整个数据库时,它会引发错误。我运行的查询:
CALL apoc.periodic.iterate(
"MATCH (n:TypeA) RETURN n;",
"WITH apoc.convert.fromJsonMap(n.propA) AS values, n
MERGE (v:TypeB)
SET v=values
WITH n,v
MERGE (v)-[:RELATION_TYPE]->(n)
RETURN v,n;
",
{batchSize:10000, parallel: false});
错误:
{
"Expected ReferenceFromSlot(2) to be a map, but it was :`NO_VALUE`": 4382
}
非常感谢您的帮助。
您的
propA
JSON 值显然与 neo4j 不兼容。要分配所有属性值(节点或关系),您的源数据必须是映射(并且每个属性值必须具有符合要求的类型)。检查所有propA
值是否符合 neo4j 要求。此外,您还有另一个严重的问题。您当前的代码不会
TypeB
为每个唯一values
映射创建一个新节点。这是因为MERGE (v:TypeB)
未指定任何属性值,因此会找到任何TypeB
节点并绑定到它(TypeB
仅当 DB 根本没有节点时才会首先创建节点TypeB
)。找到该节点后,SET v=values
将执行单独的子句。TypeB
为了做你想做的事情,
propA
JSON 需要一个唯一的标识符属性(我假设它被命名为id
),你需要更改MERGE (v:TypeB)
为类似的MERGE (v:TypeB {id: values.id})
。此外,为了提高效率并确保
MERGE
正常工作,您应该创建一个节点唯一性约束(TypeB.id
假设我的示例MERGE
发生变化)。这样做也会自动为您添加索引。