I have nodes of label TypeA which have a string property, propA. propA is a string JSON and can be converted to a map using apoc.convert.fromJsonMap().
I want to create new nodes of TypeB, whose properties are propA and create a relationship between both nodes. I have run the following query succesfully:
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;
However when I use the following with apoc.periodic.iterate to convert my entire database, it throws an error. The query I running:
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});
The error:
{
"Expected ReferenceFromSlot(2) to be a map, but it was :`NO_VALUE`": 4382
}
Any help is greatly appreciated.
Your propA
JSON values are apparently not compatible with neo4j. To assign all property values (of a node or relationship), your source data has to be a map (and each property value must have a conforming type). Check that all your propA
values are compatible with neo4j requirements.
Also, you have another serious issue. Your current code is not creating a new TypeB
node for every unique values
map. That is because MERGE (v:TypeB)
specifies no property values, and therefore finds any TypeB
node and binds to it (a TypeB
node is only created first if the DB has no TypeB
nodes at all). The separate SET v=values
clause is executed after that TypeB
node has been found.
In order to do what you want, the propA
JSON needs a unique identifier property (I will assume it is named id
), and you need to change MERGE (v:TypeB)
to something like MERGE (v:TypeB {id: values.id})
.
Also, for efficiency and to ensure that MERGE
works correctly, you should create a node-uniqueness constraint on TypeB.id
(assuming my example MERGE
change). Doing so automatically adds an index for you as well.