SET
The SET clause is used to update properties on nodes and relationships.
Set Node Properties#
Set Single Property#
MATCH (u:User {name: 'Alice'})
SET u.age = 29
RETURN u
Set Multiple Properties#
MATCH (u:User {name: 'Alice'})
SET u.age = 29, u.city = 'New York', u.updated = datetime()
RETURN u
Set from Map#
MATCH (u:User {name: 'Alice'})
SET u = {name: 'Alice', age: 29, city: 'New York'}
RETURN u
Warning: This replaces ALL properties!
Set with += (Add Properties)#
MATCH (u:User {name: 'Alice'})
SET u += {age: 29, city: 'New York'}
RETURN u
This preserves existing properties and adds/updates specified ones.
Set Relationship Properties#
MATCH (a:User)-[r:KNOWS]->(b:User)
WHERE a.name = 'Alice' AND b.name = 'Bob'
SET r.strength = 0.9, r.updated = datetime()
RETURN r
Add Labels#
Add Single Label#
MATCH (u:User {name: 'Alice'})
SET u:Premium
RETURN u
Add Multiple Labels#
MATCH (u:User {name: 'Alice'})
SET u:Premium:Verified
RETURN u
Set with Parameters#
MATCH (u:User {name: $name})
SET u.age = $age, u.city = $city
RETURN u
Python example:
graph.query("""
MATCH (u:User {name: $name})
SET u.age = $age
RETURN u
""", {
'name': 'Alice',
'age': 29
})
Conditional Set#
Set Based on Condition#
MATCH (u:User)
SET u.status = CASE
WHEN u.age < 18 THEN 'minor'
WHEN u.age >= 65 THEN 'senior'
ELSE 'adult'
END
Set If Property Exists#
MATCH (u:User)
WHERE u.tempEmail IS NOT NULL
SET u.email = u.tempEmail
REMOVE u.tempEmail
Increment/Decrement#
Increment Counter#
MATCH (p:Post {id: $postId})
SET p.views = p.views + 1
RETURN p.views
Decrement Value#
MATCH (u:User {name: 'Alice'})
SET u.credits = u.credits - 10
RETURN u.credits
Set from Expressions#
Computed Values#
MATCH (u:User)
SET u.fullName = u.firstName + ' ' + u.lastName
RETURN u
String Operations#
MATCH (u:User)
SET u.email = toLower(u.email),
u.username = trim(u.username)
RETURN u
Date/Time Operations#
MATCH (u:User)
SET u.lastLogin = datetime(),
u.sessionExpiry = datetime() + duration('PT1H')
RETURN u
Set All Properties#
Copy all properties from one node to another:
MATCH (source:User {name: 'Alice'}),
(target:User {name: 'Bob'})
SET target = properties(source)
RETURN target
Set NULL (Remove Property)#
MATCH (u:User {name: 'Alice'})
SET u.tempData = NULL
RETURN u
Or use REMOVE:
MATCH (u:User {name: 'Alice'})
REMOVE u.tempData
Bulk Updates#
Update All Matching Nodes#
MATCH (u:User)
WHERE u.active = true
SET u.lastNotified = datetime()
RETURN count(u) AS updated
Update with UNWIND#
UNWIND [
{name: 'Alice', age: 29},
{name: 'Bob', age: 33}
] AS update
MATCH (u:User {name: update.name})
SET u.age = update.age
Common Patterns#
Update or Create Timestamp#
MATCH (u:User {name: 'Alice'})
SET u.updated = datetime()
SET u.created = coalesce(u.created, datetime())
RETURN u
Increment View Counter#
MATCH (p:Post {id: $postId})
SET p.views = coalesce(p.views, 0) + 1,
p.lastViewed = datetime()
RETURN p
Toggle Boolean#
MATCH (u:User {name: 'Alice'})
SET u.active = NOT u.active
RETURN u.active
Add to Array#
MATCH (u:User {name: 'Alice'})
SET u.tags = coalesce(u.tags, []) + ['premium']
RETURN u
Update Based on Relationship#
MATCH (u:User)-[:POSTED]->(p:Post)
WITH u, count(p) AS postCount
SET u.totalPosts = postCount
RETURN u
Normalize Data#
MATCH (u:User)
SET u.email = toLower(trim(u.email)),
u.name = trim(u.name)
WHERE u.email IS NOT NULL
RETURN count(u) AS normalized
Set Default Values#
MATCH (u:User)
WHERE u.role IS NULL
SET u.role = 'user'
RETURN count(u) AS updated
SET with CREATE#
CREATE (u:User)
SET u.name = 'Alice',
u.created = datetime(),
u.id = randomUUID()
RETURN u
SET with MERGE#
MERGE (u:User {email: $email})
ON CREATE SET
u.name = $name,
u.created = datetime()
ON MATCH SET
u.lastSeen = datetime()
RETURN u
Performance Tips#
- Batch Updates ```cypher // Good: Single query updates many MATCH (u:User) WHERE u.active = true SET u.updated = datetime()
// Bad: Many individual queries // Multiple SET queries for each user ```
- Use += for Partial Updates ```cypher // Good: Only updates specified properties SET u += {age: 29}
// Bad: Replaces all properties SET u = {age: 29} ```
- Index Updated Properties ```cypher CREATE INDEX ON :User(lastLogin)
// Fast queries on updated property MATCH (u:User) WHERE u.lastLogin > datetime() - duration('P7D') RETURN u ```
- Minimize Property Writes ```cypher // Good: Only update if changed MATCH (u:User {name: 'Alice'}) WHERE u.age <> 29 SET u.age = 29
// Bad: Always writes even if unchanged MATCH (u:User {name: 'Alice'}) SET u.age = 29 ```
Common Mistakes#
Overwriting All Properties#
// WRONG: Removes all other properties
MATCH (u:User {name: 'Alice'})
SET u = {age: 29} // name is now gone!
// CORRECT: Use +=
MATCH (u:User {name: 'Alice'})
SET u += {age: 29} // name is preserved
Not Handling NULL#
// WRONG: Error if credits is NULL
SET u.credits = u.credits + 10
// CORRECT: Handle NULL
SET u.credits = coalesce(u.credits, 0) + 10
Next Steps#
- Create data with CREATE
- Delete data with DELETE
- Match patterns with MATCH
- Read Cypher Introduction