Data Model

Understand Geode’s property graph data model and how to effectively model your data using nodes, relationships, properties, and labels.

Overview

Geode implements the property graph model, a flexible and powerful way to represent connected data. Unlike relational databases with rigid table schemas or document databases with isolated documents, property graphs excel at representing and querying relationships between entities.

The property graph model consists of four fundamental concepts: nodes (entities), relationships (connections between entities), properties (key-value pairs attached to nodes and relationships), and labels (types that categorize nodes and relationships). This simple but expressive model enables natural representation of complex, interconnected data.

Property Graph Model

Core Concepts

Nodes represent entities in your domain (people, products, locations, events, etc.). Each node can have:

  • Labels: One or more type tags (e.g., :Person, :Employee)
  • Properties: Key-value pairs storing data about the entity
  • Unique ID: System-assigned identifier

Relationships represent connections between nodes. Each relationship has:

  • Type: Exactly one relationship type (e.g., :KNOWS, :WORKS_FOR)
  • Direction: Relationships are always directed (source → target)
  • Properties: Key-value pairs describing the connection
  • Unique ID: System-assigned identifier

Properties store data as key-value pairs where:

  • Keys: String identifiers (e.g., “name”, “age”, “created_at”)
  • Values: Any supported data type (see Type System below)
  • Schema-optional: Properties can be added/removed dynamically

Labels categorize nodes and relationships:

  • Multiple Labels: Nodes can have multiple labels (e.g., :Person:Employee:Manager)
  • Single Type: Relationships have exactly one type
  • Index Support: Labels enable efficient querying via indexes

Graph Example

(alice:Person {name: "Alice", age: 30})
    -[:WORKS_FOR {since: 2020, role: "Engineer"}]->
(acme:Company {name: "Acme Corp", founded: 2010})
    <-[:WORKS_FOR {since: 2021, role: "Designer"}]-
(bob:Person {name: "Bob", age: 25})

(alice)-[:KNOWS {since: 2019}]->(bob)

This simple graph represents:

  • Two people (Alice and Bob) with properties
  • One company (Acme Corp)
  • Three relationships (two WORKS_FOR, one KNOWS) with properties
  • Direction indicating who works for whom and who knows whom

Topics in This Section

  • Data Model and Types - Comprehensive guide to the property graph model, type system, and all 50+ supported data types

Type System

Geode supports 50+ specialized data types organized into categories:

Core Types

  • Primitives: NULL, BOOLEAN, INTEGER, FLOAT, STRING, BYTES
  • Temporal: DATE, TIME, TIMESTAMP, DURATION, ZONED_DATETIME
  • Collections: LIST, MAP, SET

Advanced Types

  • Geometric: POINT, LINESTRING, POLYGON, GEOGRAPHY, GEOMETRY
  • Network: IPV4, IPV6, CIDR, MAC_ADDRESS
  • Specialized: UUID, VECTOR, JSON, BIGDECIMAL, REGEX
  • Financial: MONEY, CURRENCY
  • Cryptographic: HASH, ENCRYPTED

Type Promotion and Coercion

Geode automatically promotes compatible types:

-- INTEGER to FLOAT
RETURN 1 + 2.5  -- Returns 3.5 (FLOAT)

-- STRING to TIMESTAMP
RETURN timestamp('2024-01-01')

-- LIST concatenation
RETURN [1, 2] + [3, 4]  -- Returns [1, 2, 3, 4]

See Data Model and Types for complete type reference.

Modeling Patterns

Entity Modeling

Nodes for Entities: Model domain entities as nodes with labels:

-- Single label
CREATE (:Person {name: "Alice", age: 30})

-- Multiple labels for hierarchies
CREATE (:Person:Employee:Manager {
  name: "Alice",
  employee_id: "E123",
  department: "Engineering"
})

Relationship Modeling

Relationships for Connections: Model associations as typed relationships:

-- Simple relationship
MATCH (a:Person {name: "Alice"}), (b:Person {name: "Bob"})
CREATE (a)-[:KNOWS]->(b)

-- Relationship with properties
MATCH (a:Person {name: "Alice"}), (c:Company {name: "Acme"})
CREATE (a)-[:WORKS_FOR {
  since: date('2020-01-01'),
  role: "Engineer",
  salary: money(150000, 'USD')
}]->(c)

Property Modeling

Choose Property vs. Node: General guidelines:

  • Use Properties for:

    • Attributes of an entity (name, age, email)
    • Simple values that don’t need relationships
    • Data used primarily for filtering/sorting
  • Use Nodes for:

    • Entities that have their own relationships
    • Shared reference data (cities, countries, categories)
    • Complex entities with lifecycle management
-- Property approach (simple)
CREATE (:Person {name: "Alice", city: "Seattle"})

-- Node approach (enables city relationships)
CREATE (p:Person {name: "Alice"})
CREATE (c:City {name: "Seattle", state: "WA"})
CREATE (p)-[:LIVES_IN]->(c)

Denormalization Trade-offs

Unlike relational databases, property graphs benefit from selective denormalization:

-- Normalized (requires traversal)
(:Person)-[:LIVES_IN]->(:City)-[:IN_STATE]->(:State)

-- Denormalized (faster queries, more storage)
(:Person {city: "Seattle", state: "WA"})

-- Hybrid (balanced approach)
(:Person {city: "Seattle"})-[:LIVES_IN]->(:City {state: "WA"})

Schema Design Best Practices

Label Strategy

  • Use meaningful, domain-specific labels (:Person, :Product, not :Node1)
  • Use multiple labels for hierarchies (:Person:Employee:Manager)
  • Keep label names singular (:Person not :Persons)
  • Use UPPER_SNAKE_CASE for relationship types (:WORKS_FOR)

Property Strategy

  • Store immutable data in properties (birth_date, created_at)
  • Use relationships for mutable associations (current_company, current_location)
  • Denormalize frequently accessed paths for performance
  • Normalize frequently updated data to reduce update overhead

Performance Considerations

  • Create indexes on frequently queried properties
  • Use unique constraints to prevent duplicates
  • Design relationships for primary query patterns
  • Consider cardinality when modeling relationships

See Schema Design Guide for detailed patterns.

Constraints and Validation

Geode supports schema constraints:

-- UNIQUE constraint
CREATE CONSTRAINT person_email_unique
FOR (p:Person)
REQUIRE p.email IS UNIQUE

-- NOT NULL constraint
CREATE CONSTRAINT person_name_not_null
FOR (p:Person)
REQUIRE p.name IS NOT NULL

-- NODE KEY (combined uniqueness + existence)
CREATE CONSTRAINT person_ssn_key
FOR (p:Person)
REQUIRE (p.ssn) IS NODE KEY

See Data Model and Types for constraint details.

Learn More

Examples by Domain

Social Network

CREATE GRAPH SocialNetwork;
USE SocialNetwork;

-- People
CREATE (:Person {name: "Alice", email: "[email protected]"})
CREATE (:Person {name: "Bob", email: "[email protected]"})

-- Relationships
MATCH (a:Person {name: "Alice"}), (b:Person {name: "Bob"})
CREATE (a)-[:KNOWS {since: 2020}]->(b)

-- Posts
CREATE (p:Post {
  content: "Hello, world!",
  created_at: timestamp(),
  likes: 0
})

MATCH (author:Person {name: "Alice"}), (p:Post)
CREATE (author)-[:POSTED]->(p)

E-Commerce

-- Products and Categories
CREATE (:Product {
  sku: "WIDGET-001",
  name: "Super Widget",
  price: money(29.99, 'USD')
})-[:IN_CATEGORY]->(:Category {name: "Widgets"})

-- Orders
CREATE (o:Order {
  order_id: "ORD-123",
  created_at: timestamp(),
  status: "pending"
})

MATCH (customer:Person {email: "[email protected]"}), (o:Order)
CREATE (customer)-[:PLACED]->(o)

Next Steps

Pages