One of the features of Neo4j is the ability to store complex data structures as properties of nodes and relationships. However, properties cannot contain a list of non-primitive types. This restriction can cause problems when importing data into Neo4j that contain arrays of non-primitive types.
In this article, we will demonstrate a simple workaround to this restriction that will allow you to import arrays of non-primitive types into Neo4j.
To demonstrate this workaround, we will use the example of importing a node with a list of spatial points as a property.
First, we create an Example node with a list of points as a property using the following Cypher query:
CREATE(a:Example { name:'Adam', location:[ point({latitude: 13.1, longitude: 33.46789}),
point({latitude: 14.1, longitude: 34.46789}) ] })
The resulting node will have a property called location, which is a list of points.
Now, let's add another point to the location list using the following Cypher query:
MATCH (n:Example) SET n.location = n.location + point({latitude: 15.1, longitude: 35.46789})
If we export the node using the apoc.export.json.query procedure as follows:
CALL apoc.export.json.query( "MATCH (u:Example) RETURN u", "ExportExample.json")
We get the following export file ExportExample.json that contains the Example node we created earlier. The location property contains a list of Points:
{"u":{"type":"node","id":"3",
"labels":["Example"],
"properties":
{"name":"Adam",
"location":[
{"crs":"wgs-84","latitude":13.1,"longitude":33.46789,"height":null},
{"crs":"wgs-84","latitude":14.1,"longitude":34.46789,"height":null},
{"crs":"wgs-84","latitude":15.1,"longitude":35.46789,"height":null}
]
}
}
}
Now let's try to import the node using the apoc.import.json procedure:
CALL apoc.import.json('file:////ExportExample.json') YIELD *
we will get an error similar to the following:
Property values can only be of primitive types or arrays thereof.
Encountered: Map{crs -> String("wgs-84"), latitude -> Double(5.231187e+01),
longitude -> Double(1.675980e+00), height-> NO_VALUE}.
This error occurs because the location property of the node contains a list of Points, which is a non-primitive type.
To workaround this limitation, we need to specify the type that the location property needs to be converted to during the import process. In our case, we want to convert the location property to a list of Points.
We can do this by using the nodePropertyMappings option of the apoc.import.json procedure as follows:
CALL apoc.import.json('file:////ExportExample.json',
{nodePropertyMappings: {Example: {location: "POINT"}}})
This query specifies that the location property of the Example node needs to be converted to a list of POINTS during the import process.
If we run this query, a new node with the same name and location properties as the original node will be created in the database. The location property of the new node will be a list of POINTS.
{
"identity": 9,
"labels": [
"Example"
],
"properties": {
"neo4jImportId": "343",
"name": "Adam",
"location": [
point({srid:4326, x:33.46789, y:13.1}),
point({srid:4326, x:34.46789, y:14.1}),
point({srid:4326, x:35.46789, y:15.1})
]
},
"elementId": "9"
}
In conclusion, although Neo4j has a restriction that properties cannot contain a list of non-primitive types, there is a simple workaround to this restriction. By specifying the type that a non-primitive property needs to be converted to during the import process, you can import arrays of non-primitive types into Neo4j.
Comments
0 comments
Please sign in to leave a comment.