Creating Data

The library has support for procedures that add to the write functionality that comes with Neo4j. Many of these procedures enable dynamic data creation, such as dynamically adding node labels and node or relationship properties.

Qualified Name Type Release

apoc.create.node

apoc.create.node(['Label'], {key:value,…​}) - create node with dynamic labels

Procedure

APOC Core

apoc.create.nodes

apoc.create.nodes(['Label'], [{key:value,…​}]) create multiple nodes with dynamic labels

Procedure

APOC Core

apoc.create.removeLabels

apoc.create.removeLabels( [node,id,ids,nodes], ['Label',…​]) - removes the given labels from the node or nodes

Procedure

APOC Core

apoc.create.setProperty

apoc.create.setProperty( [node,id,ids,nodes], key, value) - sets the given property on the node(s)

Procedure

APOC Core

apoc.create.setProperties

apoc.create.setProperties( [node,id,ids,nodes], [keys], [values]) - sets the given properties on the nodes(s)

Procedure

APOC Core

apoc.create.setRelProperty

apoc.create.setRelProperty( [rel,id,ids,rels], key, value) - sets the given property on the relationship(s)

Procedure

APOC Core

apoc.create.setRelProperties

apoc.create.setRelProperties( [rel,id,ids,rels], [keys], [values]) - sets the given properties on the relationship(s)

Procedure

APOC Core

apoc.create.relationship

apoc.create.relationship(person1,'KNOWS',{key:value,…​}, person2) create relationship with dynamic rel-type

Procedure

APOC Core

apoc.nodes.link

apoc.nodes.link([nodes],'REL_TYPE') - creates a linked list of nodes from first to last

Procedure

APOC Core

apoc.merge.relationship

apoc.merge.relationship(startNode, relType, identProps:{key:value, …​}, onCreateProps:{key:value, …​}, endNode, onMatchProps:{key:value, …​}) - merge relationship with dynamic type, with support for setting properties ON CREATE or ON MATCH

Procedure

APOC Core

apoc.merge.nodeWithStats

- same as apoc.merge.node providing queryStatistics into result

Procedure

APOC Core

apoc.merge.nodeWithStats.eager

- same as apoc.merge.node.eager providing queryStatistics into result

Procedure

APOC Core

apoc.merge.relationshipWithStats

- same as apoc.merge.relationship providing queryStatistics into result

Procedure

APOC Core

apoc.merge.relationshipWithStats.eager

- same as apoc.merge.relationship.eager providing queryStatistics into result

Procedure

APOC Core

apoc.create.removeProperties

apoc.create.removeProperties( [node,id,ids,nodes], [keys]) - removes the given properties from the nodes(s)

Procedure

APOC Core

apoc.create.removeRelProperties

apoc.create.removeRelProperties( [rel,id,ids,rels], [keys]) - removes the given properties from the relationship(s)

Procedure

APOC Core

Remove Node Labels

Cypher supports deleting of labels as long as the labels are hard coded. If the labels are dynamically specified, we can use the apoc.create.removeLabels procedure.

The following creates a sample graph of people:
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})
The following removes all labels except 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
Table 1. Results
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 of properties as long as the property names are hard coded. If the property names are dynamically specified we can use the apoc.create.setProperties and apoc.create.setRelProperties procedures.

The following creates a sample graph of people:
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)
The following duplicates all node properties on 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
Table 2. Results
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}

The following duplicates all relationship properties:
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
Table 3. Results
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 of properties as long as the property names are hard coded. If the property names are dynamically specified we can use the apoc.create.removeProperties and apoc.create.removeRelProperties procedures.

The following creates a sample graph of people:
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)
The following deletes all properties except for 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
Table 4. Results
node

{"name":"Jennifer"}

{"name":"Karin"}

{"name":"Elaine"}

The following deletes properties from all relationships:
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
Table 5. Results
start rel end

{"name":"Jennifer"}

{}

{"name":"Elaine"}

{"name":"Jennifer"}

{}

{"name":"Karin"}

Linked Lists

Creating a linked list from a collection of nodes can be done in Cypher, but is much easier with the apoc.nodes.link procedure.

The following creates a sample graph of events:
CREATE (:Event {name: "Event 1", date: datetime("2019-06-01")})
CREATE (:Event {name: "Event 2", date: datetime("2019-06-04")})
CREATE (:Event {name: "Event 3", date: datetime("2019-06-08")})
The following creates a linked list of these events:
MATCH (e:Event)
WITH e ORDER BY e.date
WITH collect(e) AS events
CALL apoc.nodes.link(events, "NEXT")
RETURN count(*)
linked list events