Search code examples
neo4jcypherneo4j-apoc

Neo4J APOC Periodic Iterate - ReferenceFromSlot(2) to be a map, but it was :`NO_VALUE`": 4


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.


Solution

    1. 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.

    2. 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.