Working with Nodes
Nodes are the fundamental entities in a graph database. In QilbeeDB, nodes represent entities with properties and labels.
Node Structure#
A node in QilbeeDB consists of:
- ID - Unique identifier (automatically assigned)
- Labels - One or more labels describing the node type
- Properties - Key-value pairs storing node data
┌─────────────────────────┐
│ Node ID: 123 │
├─────────────────────────┤
│ Labels: [User, Person] │
├─────────────────────────┤
│ Properties: │
│ name: "Alice" │
│ age: 28 │
│ city: "SF" │
└─────────────────────────┘
Creating Nodes#
Single Label#
from qilbeedb import QilbeeDB
db = QilbeeDB("http://localhost:7474")
graph = db.graph("my_graph")
# Create node with single label
user = graph.create_node(
['User'],
{'name': 'Alice', 'email': '[email protected]'}
)
print(f"Created node with ID: {user.id}")
Multiple Labels#
# Create node with multiple labels
person = graph.create_node(
['Person', 'User', 'Admin'],
{
'name': 'Bob',
'age': 35,
'role': 'administrator'
}
)
Cypher CREATE#
# Create node using Cypher
result = graph.query("""
CREATE (u:User {name: $name, email: $email})
RETURN u
""", {
"name": "Carol",
"email": "[email protected]"
})
Reading Nodes#
Get Node by ID#
# Retrieve node by ID
node = graph.get_node(user.id)
print(f"Name: {node.get('name')}")
print(f"Email: {node.get('email')}")
Find Nodes by Label#
# Find all nodes with specific label
users = graph.find_nodes('User')
for user in users:
print(f"User: {user.get('name')}")
Find with Limit#
# Limit number of results
recent_users = graph.find_nodes('User', limit=10)
Cypher MATCH#
# Query nodes with Cypher
results = graph.query("""
MATCH (u:User)
WHERE u.age > $min_age
RETURN u.name, u.age
ORDER BY u.age DESC
""", {"min_age": 25})
for row in results:
print(f"{row['u.name']}: {row['u.age']} years old")
Updating Nodes#
Update Properties#
# Update node properties
user.set('age', 29)
user.set('last_login', '2024-11-24')
updated_user = graph.update_node(user)
Cypher SET#
# Update using Cypher
graph.query("""
MATCH (u:User {name: $name})
SET u.age = $new_age,
u.updated_at = $timestamp
""", {
"name": "Alice",
"new_age": 30,
"timestamp": "2024-11-24T15:30:00Z"
})
Add/Remove Labels#
Coming soon - Label management operations
Deleting Nodes#
Simple Delete#
# Delete node (must have no relationships)
graph.delete_node(user.id)
Detach Delete#
# Delete node and all its relationships
graph.detach_delete_node(user.id)
Cypher DELETE#
# Delete using Cypher
graph.query("""
MATCH (u:User {name: $name})
DELETE u
""", {"name": "Alice"})
# Detach delete
graph.query("""
MATCH (u:User {name: $name})
DETACH DELETE u
""", {"name": "Bob"})
Node Properties#
Property Types#
QilbeeDB supports these property types:
- String - Text data
- Integer - Whole numbers
- Float - Decimal numbers
- Boolean - true/false
- DateTime - Timestamps
- Array - Lists of values (same type)
node = graph.create_node(
['Example'],
{
'text': 'Hello',
'number': 42,
'decimal': 3.14,
'flag': True,
'created': '2024-11-24T15:30:00Z',
'tags': ['python', 'graph', 'database']
}
)
Access Properties#
# Get property
name = node.get('name')
# Get with default
email = node.get('email', '[email protected]')
# Set property
node.set('verified', True)
# Get all properties
props = node.properties
Node Labels#
Multi-Label Nodes#
Nodes can have multiple labels for flexible classification:
# User who is also an admin
admin_user = graph.create_node(
['User', 'Admin'],
{'name': 'Alice', 'permissions': 'all'}
)
# Student who is also a teacher
student_teacher = graph.create_node(
['Student', 'Teacher'],
{'name': 'Bob', 'subjects': ['Math', 'Physics']}
)
Query by Multiple Labels#
# Find nodes with all specified labels
results = graph.query("""
MATCH (n:User:Admin)
RETURN n.name
""")
Best Practices#
1. Use Meaningful Labels#
# Good: Descriptive labels
graph.create_node(['Customer', 'PremiumMember'], {...})
# Bad: Generic labels
graph.create_node(['Entity', 'Thing'], {...})
2. Keep Properties Simple#
# Good: Simple, flat properties
node = graph.create_node(['User'], {
'name': 'Alice',
'email': '[email protected]',
'age': 28
})
# Avoid: Complex nested structures
# Use relationships instead
3. Use Consistent Naming#
# Good: Consistent naming convention
graph.create_node(['User'], {
'user_id': 'U123',
'first_name': 'Alice',
'last_name': 'Johnson',
'created_at': '2024-11-24'
})
4. Index Frequently Queried Properties#
# Create index for fast lookups
# (Index operations coming soon)
Common Patterns#
Upsert (Create or Update)#
# Create if not exists, update if exists
result = graph.query("""
MERGE (u:User {email: $email})
ON CREATE SET u.name = $name, u.created = timestamp()
ON MATCH SET u.last_seen = timestamp()
RETURN u
""", {
"email": "[email protected]",
"name": "Alice"
})
Bulk Creation#
# Create multiple nodes efficiently
users_data = [
{'name': 'Alice', 'age': 28},
{'name': 'Bob', 'age': 32},
{'name': 'Carol', 'age': 26}
]
created_nodes = []
for user_data in users_data:
node = graph.create_node(['User'], user_data)
created_nodes.append(node)
Conditional Updates#
# Update only if condition met
graph.query("""
MATCH (u:User {name: $name})
WHERE u.age < $max_age
SET u.status = 'active'
""", {
"name": "Alice",
"max_age": 65
})
Next Steps#
- Learn about Relationships
- Understand Properties in detail
- Create Indexes for performance
- Use Transactions for data integrity