Graph Database: Cypher Query Language
Graph Database: Cypher Query Language
Part of: Graph Database User Guide
HeliosDB supports a Cypher-like query language for declarative graph queries. This section covers all query clauses with examples.
MATCH Patterns
The MATCH clause finds patterns in the graph.
Example 1: Simple Node Match
// Find all Person nodeslet query = CypherQuery { match_clause: Some(MatchClause { patterns: vec![Pattern { nodes: vec![NodePattern { variable: "p".to_string(), labels: vec!["Person".to_string()], properties: HashMap::new(), }], relationships: vec![], }], }), return_clause: ReturnClause { items: vec![ReturnItem { expression: Expression::Property { variable: "p".to_string(), property: "name".to_string(), }, alias: Some("name".to_string()), }], distinct: false, }, where_clause: None, order_by: None, limit: None, skip: None,};Example 2: Match with Relationship
// Find who follows whomlet query = CypherQuery { match_clause: Some(MatchClause { patterns: vec![Pattern { nodes: vec![ NodePattern { variable: "follower".to_string(), labels: vec!["User".to_string()], properties: HashMap::new(), }, NodePattern { variable: "followed".to_string(), labels: vec!["User".to_string()], properties: HashMap::new(), }, ], relationships: vec![RelationshipPattern { variable: Some("rel".to_string()), types: vec!["FOLLOWS".to_string()], direction: Direction::Outgoing, properties: HashMap::new(), length: PathLength::Fixed(1), }], }], }), return_clause: ReturnClause { items: vec![ ReturnItem { expression: Expression::Property { variable: "follower".to_string(), property: "username".to_string(), }, alias: Some("follower".to_string()), }, ReturnItem { expression: Expression::Property { variable: "followed".to_string(), property: "username".to_string(), }, alias: Some("followed".to_string()), }, ], distinct: false, }, where_clause: None, order_by: None, limit: None, skip: None,};WHERE Filtering
Filter results based on conditions.
Example 3: Filter by Property
use heliosdb_graph::cypher::{WhereClause, Condition, ComparisonOp};
let query = CypherQuery { match_clause: Some(MatchClause { patterns: vec![Pattern { nodes: vec![NodePattern { variable: "p".to_string(), labels: vec!["Person".to_string()], properties: HashMap::new(), }], relationships: vec![], }], }), where_clause: Some(WhereClause { condition: Condition::Comparison { left: Expression::Property { variable: "p".to_string(), property: "age".to_string(), }, op: ComparisonOp::Gt, right: Expression::Literal(json!(25)), }, }), return_clause: ReturnClause { items: vec![ReturnItem { expression: Expression::Property { variable: "p".to_string(), property: "name".to_string(), }, alias: Some("name".to_string()), }], distinct: false, }, order_by: None, limit: None, skip: None,};Example 4: Complex Conditions (AND/OR)
let query = CypherQuery { match_clause: Some(MatchClause { patterns: vec![Pattern { nodes: vec![NodePattern { variable: "p".to_string(), labels: vec!["Person".to_string()], properties: HashMap::new(), }], relationships: vec![], }], }), where_clause: Some(WhereClause { condition: Condition::And( Box::new(Condition::Comparison { left: Expression::Property { variable: "p".to_string(), property: "age".to_string(), }, op: ComparisonOp::Ge, right: Expression::Literal(json!(25)), }), Box::new(Condition::Comparison { left: Expression::Property { variable: "p".to_string(), property: "city".to_string(), }, op: ComparisonOp::Eq, right: Expression::Literal(json!("San Francisco")), }), ), }), return_clause: ReturnClause { items: vec![ReturnItem { expression: Expression::Property { variable: "p".to_string(), property: "name".to_string(), }, alias: Some("name".to_string()), }], distinct: false, }, order_by: None, limit: None, skip: None,};
// Equivalent Cypher:// MATCH (p:Person)// WHERE p.age >= 25 AND p.city = 'San Francisco'// RETURN p.nameRETURN Projections
Specify what data to return.
Example 5: Return Multiple Properties
let return_clause = ReturnClause { items: vec![ ReturnItem { expression: Expression::Property { variable: "p".to_string(), property: "name".to_string(), }, alias: Some("person_name".to_string()), }, ReturnItem { expression: Expression::Property { variable: "p".to_string(), property: "age".to_string(), }, alias: Some("person_age".to_string()), }, ReturnItem { expression: Expression::Property { variable: "p".to_string(), property: "email".to_string(), }, alias: Some("email".to_string()), }, ], distinct: false,};Example 6: DISTINCT Results
let return_clause = ReturnClause { items: vec![ReturnItem { expression: Expression::Property { variable: "p".to_string(), property: "city".to_string(), }, alias: Some("city".to_string()), }], distinct: true, // Remove duplicates};CREATE Nodes/Edges
Add new data to the graph.
Example 7: Create Node
// Create a new personlet new_person = Node { id: 0, label: "Person".to_string(), properties: HashMap::from([ ("name".to_string(), json!("Diana")), ("age".to_string(), json!(30)), ("city".to_string(), json!("Seattle")), ]),};
let diana_id = storage.add_vertex(new_person).await?;println!("Created node with ID: {}", diana_id);Example 8: Create Relationship
// Create friendship between Alice and Dianalet friendship = Edge { id: 0, source: alice_id, target: diana_id, label: "FRIEND_OF".to_string(), weight: 1.0, properties: HashMap::from([ ("since".to_string(), json!("2024-11-01")), ("strength".to_string(), json!(0.8)), ]),};
let edge_id = storage.add_edge(friendship).await?;println!("Created edge with ID: {}", edge_id);UPDATE Properties
Modify existing nodes or edges.
Example 9: Update Node Properties
// Get the nodeif let Some(mut node) = storage.get_vertex(alice_id).await? { // Update properties node.properties.insert("age".to_string(), json!(29)); node.properties.insert("last_updated".to_string(), json!("2025-11-02"));
// Save (this would require update_vertex method) // storage.update_vertex(node).await?;}DELETE Nodes/Edges
Remove data from the graph.
Example 10: Delete Edge
// Delete a specific edge// storage.delete_edge(edge_id).await?;Example 11: Delete Node
// Delete a node (and optionally its edges)// storage.delete_vertex(alice_id, true).await?; // true = cascade delete edgesORDER BY, LIMIT, SKIP
Control result ordering and pagination.
Example 12: Order and Limit Results
use heliosdb_graph::cypher::{OrderByClause, OrderByItem};
let query = CypherQuery { match_clause: Some(MatchClause { patterns: vec![Pattern { nodes: vec![NodePattern { variable: "p".to_string(), labels: vec!["Person".to_string()], properties: HashMap::new(), }], relationships: vec![], }], }), where_clause: None, return_clause: ReturnClause { items: vec![ ReturnItem { expression: Expression::Property { variable: "p".to_string(), property: "name".to_string(), }, alias: Some("name".to_string()), }, ReturnItem { expression: Expression::Property { variable: "p".to_string(), property: "age".to_string(), }, alias: Some("age".to_string()), }, ], distinct: false, }, order_by: Some(OrderByClause { items: vec![OrderByItem { expression: Expression::Property { variable: "p".to_string(), property: "age".to_string(), }, ascending: false, // Descending order }], }), limit: Some(10), // Top 10 results skip: Some(0),};
// Equivalent Cypher:// MATCH (p:Person)// RETURN p.name AS name, p.age AS age// ORDER BY p.age DESC// LIMIT 10Example 13: Pagination
// Page 1 (results 1-10)let page1_query = CypherQuery { // ... match and return clauses ... order_by: Some(OrderByClause { /* ... */ }), limit: Some(10), skip: Some(0), // ...};
// Page 2 (results 11-20)let page2_query = CypherQuery { // ... match and return clauses ... order_by: Some(OrderByClause { /* ... */ }), limit: Some(10), skip: Some(10), // ...};
// Page 3 (results 21-30)let page3_query = CypherQuery { // ... match and return clauses ... order_by: Some(OrderByClause { /* ... */ }), limit: Some(10), skip: Some(20), // ...};Navigation
- Previous: Quick Start
- Next: Graph Patterns
- Index: Graph Database User Guide
Version: 6.5 Last Updated: November 17, 2025