VOOZH about

URL: https://deepwiki.com/stefanak-michal/php-bolt-driver/7.2-graph-structures

⇱ Graph Structures | stefanak-michal/php-bolt-driver | DeepWiki


Loading...
Last indexed: 14 February 2026 (a283bd)
Menu

Graph Structures

Purpose and Scope

This document describes the graph structures used in the Bolt protocol to represent Neo4j graph elements: Node, Relationship, UnboundRelationship, and Path. These structures are returned by the database when executing queries that retrieve graph data. Unlike temporal and spatial types (see Temporal and Spatial Types), graph structures are unpack-only — they can be received from the server but cannot be sent as query parameters.

For information about the PackStream serialization format used to transmit these structures, see PackStream Format and Type Mapping.


Graph Structures Overview

Graph structures represent the fundamental elements of a property graph database. When a Cypher query returns nodes, relationships, or paths, the Bolt protocol serializes them as typed structures with specific signature bytes.


Sources: README.md166-168 tests/structures/v1/StructuresTest.php1-439


Unpack-Only Restriction

Graph structures are unpack-only, meaning they can only be received from the database, not sent as query parameters. This is explicitly documented and enforced by the library.

Structure TypePack SupportUnpack SupportUsage
Node❌ No✅ YesReceived from database queries
Relationship❌ No✅ YesReceived from database queries
UnboundRelationship❌ No✅ YesReceived within Path structures
Path❌ No✅ YesReceived from database queries

If you need to reference a node or relationship in a query, use its id or element_id as an integer or string parameter instead of attempting to pass the structure itself.

Sources: README.md167-168 tests/structures/v1/StructuresTest.php254 tests/structures/v1/StructuresTest.php284 tests/structures/v1/StructuresTest.php368


Node Structure

The Node structure represents a graph node with labels and properties. It is identified by PackStream signature byte 0x4E.

Structure Definition


Version Differences

Protocol VersionPropertiesDescription
V1 - V4.4id, labels, propertiesLegacy numeric identifier
V5+id, labels, properties, element_idAdds string-based element identifier

The element_id property was introduced in Neo4j 5.0 to support larger-scale graphs where numeric IDs became insufficient. For backward compatibility, the id property is still present in V5+.

Example Usage


Sources: tests/structures/v1/StructuresTest.php236-257 tests/structures/v5/StructuresTest.php55-77 tests/NornicDBTest.php92


Relationship Structure

The Relationship structure represents a directed relationship between two nodes. It is identified by PackStream signature byte 0x52.

Structure Definition


Version Differences

Protocol VersionPropertiesDescription
V1 - V4.4id, startNodeId, endNodeId, type, propertiesLegacy numeric identifiers
V5+All V1 properties plus element_id, start_node_element_id, end_node_element_idString-based identifiers for relationship and connected nodes

The relationship structure includes both the relationship's own identity and the identities of the nodes it connects.

Example Usage


Sources: tests/structures/v1/StructuresTest.php348-371 tests/structures/v5/StructuresTest.php113-139 tests/NornicDBTest.php115-130


UnboundRelationship Structure

The UnboundRelationship structure represents a relationship without its start and end node identifiers. It is identified by PackStream signature byte 0x72 and is used exclusively within Path structures.

Structure Definition


Why UnboundRelationship?

Unlike the Relationship structure, UnboundRelationship does not contain startNodeId and endNodeId fields. This is because within a Path, the relationship's connectivity is determined by the indices array rather than being stored redundantly in each relationship object. This reduces the serialized size of path structures.

Version Differences

Protocol VersionPropertiesDescription
V1 - V4.4id, type, propertiesMinimal relationship data
V5+All V1 properties plus element_idAdds string-based identifier

Sources: tests/structures/v1/StructuresTest.php276-282 tests/structures/v5/StructuresTest.php96-103 tests/NornicDBTest.php154


Path Structure

The Path structure represents a sequence of alternating nodes and relationships forming a path through the graph. It is identified by PackStream signature byte 0x50.

Structure Definition


Path Components

PropertyTypeDescription
nodesarray<Node>All nodes in the path, in order of traversal
relsarray<UnboundRelationship>All relationships in the path
indicesarray<int>Encodes the path topology and relationship directions

Understanding the Indices Array

The indices array encodes the path structure using a compact representation:

  • Positive index: Relationship at abs(index) - 1 goes forward (from previous node to next node)
  • Negative index: Relationship at abs(index) - 1 goes backward (from next node to previous node)

For a path (A)-[r1]->(B)<-[r2]-(C):

  • nodes = [A, B, C]
  • rels = [r1, r2]
  • indices = [1, -2] (r1 forward from A to B, r2 backward from C to B)

Example Usage


Sources: tests/structures/v1/StructuresTest.php262-287 tests/structures/v5/StructuresTest.php82-108 tests/NornicDBTest.php137-160


PackStream Signatures

Each graph structure is identified by a unique signature byte in the PackStream format:










































StructureSignature Byte (Hex)Signature Byte (ASCII)Fields Count (V1-V4.4)Fields Count (V5+)
Node0x4E'N'34
Relationship0x52'R'58
UnboundRelationship0x72'r'34
Path0x50'P'33

These signatures are used by the Unpacker to determine which structure class to instantiate when deserializing binary data.

Sources: README.md159 tests/structures/v1/StructuresTest.php236-371 tests/structures/v5/StructuresTest.php55-139


Version Evolution: id vs element_id

Neo4j 5.0 introduced element_id as a string-based identifier to replace the numeric id property for improved scalability. The Bolt protocol reflects this change in its structure definitions.


Migration Considerations

When working with both old and new Neo4j versions:

  1. V1-V4.4 protocols: Only id properties are available (integers)
  2. V5+ protocols: Both id and element_id properties are available
  3. Forward compatibility: Prefer using element_id when available for future-proofing
  4. Query compatibility: Neo4j 5.0+ supports both ID() and elementId() functions in Cypher

Sources: tests/structures/v1/StructuresTest.php236-257 tests/structures/v5/StructuresTest.php55-77 tests/structures/v5/StructuresTest.php113-139


Structure Class Locations

Graph structure classes are organized by protocol version:






















Protocol VersionNamespaceNotes
V1-V4.4Bolt\protocol\v1\structures\Base implementations
V5+Bolt\protocol\v5\structures\Extended with element_id fields

The Path structure remains unchanged in V5+ and is reused from the V1 namespace, as only its contained Node and UnboundRelationship structures differ between versions.

Sources: tests/structures/v1/StructuresTest.php13-27 tests/structures/v5/StructuresTest.php7-14


Testing Graph Structures

The library includes comprehensive tests for graph structures across different protocol versions and database implementations:

Test Coverage

Test SuiteProtocol VersionsDatabasePurpose
tests/structures/v1/StructuresTest.phpV3, V4.2, V4.3, V4.4Neo4jV1-V4.4 structure validation
tests/structures/v5/StructuresTest.phpV5.0-V5.8Neo4jV5+ structure validation with element_id
tests/structures/v4_3/StructuresTest.phpV4.3, V4.4Neo4jEnhanced structure tests
tests/NornicDBTest.phpV4.4NornicDBAlternative database compatibility

Test Patterns

All structure tests follow a consistent pattern:

  1. Create test data within a transaction
  2. Execute query returning the structure
  3. Validate structure type using assertInstanceOf()
  4. Verify properties match expected values
  5. Rollback transaction to clean up

Sources: tests/structures/v1/StructuresTest.php236-257 tests/structures/v5/StructuresTest.php55-77 tests/NornicDBTest.php77-108 phpunit.xml4-11