Creating data
The APOC library contains procedures which enhance Neo4j’s write functionality. Many of these procedures enable dynamic data creation, such as dynamically adding node labels.
For an explanation of how to create nodes and relationships dynamically using the APOC library by Michael Hunger, Senior Director of User Innovation at Neo4j, watch this video:
Functions for creating data dynamically
| Qualified Name | Type |
|---|---|
|
Procedure Deprecated in Cypher 25 |
|
Procedure Deprecated in Cypher 25 |
|
Procedure Deprecated in Cypher 25 |
|
Procedure Deprecated in Cypher 25 |
|
Procedure Deprecated in Cypher 25 |
|
Procedure Deprecated in Cypher 25 |
|
Procedure Deprecated in Cypher 25 |
|
Procedure Deprecated in Cypher 25 |
|
Procedure Deprecated in Cypher 25 |
|
Procedure Deprecated in Cypher 25 |
|
Procedure |
|
Procedure |
|
Procedure |
|
Procedure |
|
Procedure |
|
Procedure |
Examples
The below examples will further explain these procedures.
Remove Node Labels
Cypher supports deleting labels as long as the labels are hard coded.
If the labels are dynamically specified, the apoc.create.removeLabels procedure can be used.
CREATE (jennifer:Person:US {name: "Jennifer", community: 1, partition: 4})
CREATE (karin:Person:US {name: "Karin", community: 4, partition: 2})
CREATE (mark:Person:UK {name: "Mark", community: 3, partition: 3})
Person from all nodes:CALL db.labels()
YIELD label WHERE label <> "Person"
WITH collect(label) AS labels
MATCH (p:Person)
WITH collect(p) AS people, labels
CALL apoc.create.removeLabels(people, labels)
YIELD node
RETURN node, labels(node) AS labels
| node | labels |
|---|---|
(:Person {name: "Jennifer", partition: 4, community: 1}) |
["Person"] |
(:Person {name: "Karin", partition: 2, community: 4}) |
["Person"] |
(:Person {name: "Mark", partition: 3, community: 3}) |
["Person"] |
Set Node and Relationship Properties
Cypher supports setting properties as long as the property names are hard coded.
If the property names are dynamically specified, use the apoc.create.setProperties and apoc.create.setRelProperties procedures.
CREATE (jennifer:Person {name: "Jennifer", community: 1, partition: 4})
CREATE (karin:Person {name: "Karin", community: 4, partition: 2})
CREATE (elaine:Person {name: "Elaine", community: 3, partition: 3})
MERGE (jennifer)-[:FRIENDS {since: datetime("2019-06-01")}]-(karin)
MERGE (jennifer)-[:FRIENDS {since: datetime("2019-05-04")}]-(elaine)
Person nodes:MATCH (p:Person)
WITH p, keys(p) AS keys
CALL apoc.create.setProperties(p,[k in keys | k + "Copy"], [k in keys | p[k]])
YIELD node
RETURN node
| node |
|---|
{"name":"Jennifer","partition":4,"community":1,"nameCopy":"Jennifer","partitionCopy":4,"communityCopy":1} |
{"name":"Karin","partition":2,"community":4,"nameCopy":"Karin","partitionCopy":2,"communityCopy":4} |
{"name":"Mark","partition":3,"community":3,"nameCopy":"Mark","partitionCopy":3,"communityCopy":3} |
MATCH (:Person)-[friends:FRIENDS]->(:Person)
WITH friends, keys(friends) AS keys
CALL apoc.create.setRelProperties(friends,[k in keys | k + "Copy"], [k in keys | friends[k]])
YIELD rel
RETURN startNode(rel) AS start, rel, endNode(rel) AS end
| start | rel | end |
|---|---|---|
{ "name": "Jennifer", "partition": 4, "community": 1, "nameCopy": "Jennifer", "partitionCopy": 4, "communityCopy": 1 } |
{ "sinceCopy": "2019-05-04T00:00:00Z", "since": "2019-05-04T00:00:00Z" } |
{ "name": "Elaine", "partition": 3, "community": 3, "nameCopy": "Elaine", "partitionCopy": 3, "communityCopy": 3 } |
{ "name": "Jennifer", "partition": 4, "community": 1, "nameCopy": "Jennifer", "partitionCopy": 4, "communityCopy": 1 } |
{ "sinceCopy": "2019-06-01T00:00:00Z", "since": "2019-06-01T00:00:00Z" } |
{ "name": "Karin", "partition": 2, "community": 4, "nameCopy": "Karin", "partitionCopy": 2, "communityCopy": 4 } |
Remove Node and Relationship Properties
Cypher supports deleting properties as long as the property names are hard coded.
If the property names are dynamically specified, use the apoc.create.removeProperties and apoc.create.removeRelProperties procedures.
CREATE (jennifer:Person {name: "Jennifer", community: 1, partition: 4})
CREATE (karin:Person {name: "Karin", community: 4, partition: 2})
CREATE (elaine:Person {name: "Elaine", community: 3, partition: 3})
MERGE (jennifer)-[:FRIENDS {since: datetime("2019-06-01")}]-(karin)
MERGE (jennifer)-[:FRIENDS {since: datetime("2019-05-04")}]-(elaine)
name from Person nodes:CALL db.propertyKeys()
YIELD propertyKey WHERE propertyKey <> "name"
WITH collect(propertyKey) AS propertyKeys
MATCH (p:Person)
WITH collect(p) AS nodes, propertyKeys
CALL apoc.create.removeProperties(nodes, propertyKeys)
YIELD node
RETURN node
| node |
|---|
{"name":"Jennifer"} |
{"name":"Karin"} |
{"name":"Elaine"} |
CALL db.propertyKeys()
YIELD propertyKey
WITH collect(propertyKey) AS propertyKeys
MATCH (:Person)-[friends:FRIENDS]->(:Person)
WITH collect(friends) AS friendsRels, propertyKeys
CALL apoc.create.removeRelProperties(friendsRels, propertyKeys)
YIELD rel
RETURN startNode(rel) AS start, rel, endNode(rel) AS end
| start | rel | end |
|---|---|---|
{"name":"Jennifer"} |
{} |
{"name":"Elaine"} |
{"name":"Jennifer"} |
{} |
{"name":"Karin"} |
Linked Lists
apoc.nodes.link can be used to create a linked list of nodes.
MATCH (e:Event)
WITH e ORDER BY e.date
WITH collect(e) AS events
CALL apoc.nodes.link(events, "NEXT")
RETURN count(*);
Linked lists can also be created using Cypher.
MATCH (e:Event)
WITH e ORDER BY e.date
WITH collect(e) AS events, count(e) as size
CALL {
WITH events, size
UNWIND range(0, size - 2) as i
WITH events[i] as a, events[i+1] as b
MERGE (a)-[:NEXT]->(b)
}
RETURN events