Skip to content

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

  1. Batch Updates

    // 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
    

  2. Use += for Partial Updates

    // Good: Only updates specified properties
    SET u += {age: 29}
    
    // Bad: Replaces all properties
    SET u = {age: 29}
    

  3. Index Updated Properties

    CREATE INDEX ON :User(lastLogin)
    
    // Fast queries on updated property
    MATCH (u:User)
    WHERE u.lastLogin > datetime() - duration('P7D')
    RETURN u
    

  4. Minimize Property Writes

    // 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