graph

package
v0.2.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 28, 2026 License: MIT Imports: 6 Imported by: 1

Documentation

Overview

Package graph provides core data structures and interfaces for the gograph database. It includes Node, Relationship, and Property types along with utilities for indexing and adjacency list management.

Package graph provides core data structures and interfaces for the gograph database.

Package graph provides core data structures and interfaces for the gograph database.

Package graph provides core data structures and interfaces for the gograph database.

Package graph provides core data structures and interfaces for the gograph database. It implements a property graph model where data is organized as nodes connected by relationships, with both nodes and relationships capable of holding properties.

Graph Model:

┌─────────────┐         ┌─────────────┐
│    Node     │◀───────▶│  Relationship
│  (Person)   │         │   (KNOWS)   │
├─────────────┤         ├─────────────┤
│ ID          │         │ ID          │
│ Labels      │         │ Type        │
│ Properties  │         │ StartNodeID │
└─────────────┘         │ EndNodeID   │
                        │ Properties  │
                        └─────────────┘

Basic Usage:

// Create a node with labels and properties
node := graph.NewNode(
    []string{"Person"},
    map[string]interface{}{
        "name": "Alice",
        "age":  30,
    },
)

// Check if node has a label
if node.HasLabel("Person") {
    fmt.Println("This is a person node")
}

// Get and set properties
name, _ := node.GetProperty("name")
node.SetProperty("age", graph.NewIntProperty(31))

Thread Safety:

Node and Relationship types are not thread-safe. If you need to access them concurrently, use external synchronization mechanisms.

Package graph provides core data structures and interfaces for the gograph database.

Package graph provides core data structures and interfaces for the gograph database.

Package graph provides core data structures and interfaces for the gograph database.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func EncodePropertyValue

func EncodePropertyValue(v PropertyValue) string

EncodePropertyValue encodes a PropertyValue to a string for indexing. This is used internally for creating index keys.

Parameters:

  • v: The PropertyValue to encode

Returns a string representation suitable for indexing.

func GenerateID

func GenerateID(prefix string) string

GenerateID generates a unique ID with the given prefix. It uses an atomic counter to ensure uniqueness across concurrent operations.

The generated ID has the format: "prefix:XY" where:

  • prefix is the provided prefix string
  • X is a letter (a-z) based on the counter value
  • Y is a digit (0-9) based on the counter value

Parameters:

  • prefix: The prefix to use for the ID (e.g., "node", "rel")

Returns a unique string identifier.

Example:

id1 := graph.GenerateID("node") // e.g., "node:a1"
id2 := graph.GenerateID("rel")  // e.g., "rel:b2"

func SetIDCounter

func SetIDCounter(counter uint64)

SetIDCounter sets the ID counter to a specific value. This is primarily useful for testing purposes to ensure predictable IDs.

Parameters:

  • counter: The value to set the counter to

Example:

// In test setup
graph.SetIDCounter(0)
id := graph.GenerateID("node") // Will generate "node:a1"

Types

type AdjacencyList

type AdjacencyList struct {
	// contains filtered or unexported fields
}

AdjacencyList manages the adjacency relationships between nodes. It provides methods to build and query relationships between graph nodes, enabling efficient traversal of the graph structure.

The adjacency list stores relationships in both directions:

  • Outgoing: From start node to end node
  • Incoming: From end node to start node

This allows for efficient querying of relationships in either direction.

Example:

adj := graph.NewAdjacencyList(store)

// Add a relationship to the adjacency list
err := adj.AddRelationship(mutator, relationship)

// Query related nodes
related, err := adj.GetRelatedNodes(nodeID, "KNOWS", graph.DirectionOutgoing)

func NewAdjacencyList

func NewAdjacencyList(store *storage.DB) *AdjacencyList

NewAdjacencyList creates a new AdjacencyList instance.

Parameters:

  • store: The storage database to use for adjacency data

Returns a new AdjacencyList ready to manage relationships.

Example:

store, _ := storage.Open("/path/to/db")
adj := graph.NewAdjacencyList(store)

func (*AdjacencyList) AddRelationship

func (adj *AdjacencyList) AddRelationship(m Mutator, rel *Relationship) error

AddRelationship creates adjacency entries for a relationship within a mutation context. It creates both outgoing and incoming entries to enable bidirectional traversal.

Parameters:

  • m: The Mutator to use for the operation
  • rel: The relationship to add to the adjacency list

Returns an error if the operation fails.

Example:

err := adj.AddRelationship(mutator, relationship)
if err != nil {
    log.Fatal(err)
}

func (*AdjacencyList) GetAllRelated

func (adj *AdjacencyList) GetAllRelated(nodeID string) ([]string, error)

GetAllRelated returns all Relationship IDs related to the given node, regardless of type. This is critical for efficient `Detach Delete` operations.

Parameters:

  • nodeID: The ID of the node to find all relationships for

Returns a slice of relationship IDs, or an error if the query fails.

Example:

// Get all relationships for a node (for detach delete)
relIDs, err := adj.GetAllRelated(nodeID)
if err != nil {
    log.Fatal(err)
}
for _, relID := range relIDs {
    fmt.Printf("Relationship: %s\n", relID)
}

func (*AdjacencyList) GetRelatedNodes

func (adj *AdjacencyList) GetRelatedNodes(nodeID, relType string, direction Direction) ([]string, error)

GetRelatedNodes returns the IDs of nodes related to the given node with the specified relationship type and direction.

Parameters:

  • nodeID: The ID of the node to find relationships for
  • relType: The type of relationship to look for
  • direction: The direction of relationships to query (outgoing, incoming, or both)

Returns a slice of node IDs that are related to the given node, or an error if the query fails.

Example:

// Get all nodes that this node knows
related, err := adj.GetRelatedNodes(nodeID, "KNOWS", graph.DirectionOutgoing)
if err != nil {
    log.Fatal(err)
}
for _, id := range related {
    fmt.Printf("Related node: %s\n", id)
}

func (*AdjacencyList) RemoveRelationship

func (adj *AdjacencyList) RemoveRelationship(m Mutator, rel *Relationship) error

RemoveRelationship removes adjacency entries for a relationship within a mutation context. It removes both outgoing and incoming entries.

Parameters:

  • m: The Mutator to use for the operation
  • rel: The relationship to remove from the adjacency list

Returns an error if the operation fails.

Example:

err := adj.RemoveRelationship(mutator, relationship)
if err != nil {
    log.Fatal(err)
}

type Direction

type Direction string

Direction represents the direction of a relationship in a graph. It is used when traversing relationships to specify which direction to follow from a starting node.

The three possible directions are:

  • DirectionOutgoing: From start node to end node (->)
  • DirectionIncoming: From end node to start node (<-)
  • DirectionBoth: Both directions (-)

Example:

// Query outgoing relationships
related, _ := adjacencyList.GetRelatedNodes(nodeID, "KNOWS", DirectionOutgoing)

// Query incoming relationships
related, _ := adjacencyList.GetRelatedNodes(nodeID, "FOLLOWS", DirectionIncoming)

// Query relationships in both directions
related, _ := adjacencyList.GetRelatedNodes(nodeID, "CONNECTED", DirectionBoth)
const (
	// DirectionOutgoing represents relationships going out from a node.
	// In Cypher syntax, this is represented as "->".
	DirectionOutgoing Direction = "outgoing"

	// DirectionIncoming represents relationships coming into a node.
	// In Cypher syntax, this is represented as "<-".
	DirectionIncoming Direction = "incoming"

	// DirectionBoth represents relationships in either direction.
	// In Cypher syntax, this is represented as "-".
	DirectionBoth Direction = "both"
)

func ParseDirection

func ParseDirection(s string) (Direction, error)

ParseDirection parses a direction string and returns the corresponding Direction. It supports multiple formats for each direction:

  • Outgoing: "outgoing", "->", "out"
  • Incoming: "incoming", "<-", "in"
  • Both: "both", "-"

Parameters:

  • s: The direction string to parse

Returns the Direction constant and nil error on success, or DirectionOutgoing and an error if the string cannot be parsed.

Example:

dir, err := graph.ParseDirection("->")
if err != nil {
    log.Fatal(err)
}
fmt.Println(dir) // Output: outgoing

func (Direction) String

func (d Direction) String() string

String returns the string representation of the direction. This implements the fmt.Stringer interface.

Returns "outgoing", "incoming", or "both".

Example:

fmt.Println(DirectionOutgoing) // Output: outgoing

type Index

type Index struct {
	// contains filtered or unexported fields
}

Index manages label and property indexes for efficient node lookups.

func NewIndex

func NewIndex(store *storage.DB) *Index

NewIndex creates a new Index instance for the given storage.

func (*Index) BuildLabelIndex

func (idx *Index) BuildLabelIndex(m Mutator, node *Node) error

BuildLabelIndex creates index entries for all labels on a node.

func (*Index) BuildPropertyIndex

func (idx *Index) BuildPropertyIndex(m Mutator, node *Node) error

BuildPropertyIndex creates index entries for all properties on a node.

func (*Index) LookupByLabel

func (idx *Index) LookupByLabel(label string) ([]string, error)

LookupByLabel returns all node IDs that have the given label.

func (*Index) LookupByProperty

func (idx *Index) LookupByProperty(label, propName, propValue string) ([]string, error)

LookupByProperty returns all node IDs that have the given label and property value.

func (*Index) RemoveLabelIndex

func (idx *Index) RemoveLabelIndex(m Mutator, node *Node) error

RemoveLabelIndex removes index entries for all labels on a node.

func (*Index) RemovePropertyIndex

func (idx *Index) RemovePropertyIndex(m Mutator, node *Node) error

RemovePropertyIndex removes index entries for all properties on a node.

type Mutator

type Mutator interface {
	Put(key, value []byte) error
	Delete(key []byte) error
}

Mutator defines the interface for modifying storage, satisfied by *tx.Transaction.

type Node

type Node struct {
	// ID is the unique identifier for this node.
	ID string

	// Labels are the categories or types this node belongs to.
	// A node can have multiple labels (e.g., ["Person", "Employee"]).
	Labels []string

	// Properties are the key-value pairs associated with this node.
	// Values are stored as PropertyValue which supports string, int, float, and bool.
	Properties map[string]PropertyValue
}

Node represents a graph node with an ID, labels, and properties. Nodes are the primary entities in a graph database, representing objects such as people, places, or things.

Each node has:

  • A unique identifier (ID)
  • One or more labels that categorize the node
  • A map of properties that store data as key-value pairs

func NewNode

func NewNode(labels []string, properties map[string]interface{}) *Node

NewNode creates a new Node with the given labels and properties.

Parameters:

  • labels: The categories or types for this node (e.g., ["Person"])
  • properties: A map of property names to values. Values can be string, int, int64, float64, or bool. Other types will be converted to strings.

Returns a new Node with a generated unique ID.

Example:

node := graph.NewNode(
    []string{"Person"},
    map[string]interface{}{
        "name":    "Alice",
        "age":     30,
        "active":  true,
        "balance": 1234.56,
    },
)

func (*Node) GetProperty

func (n *Node) GetProperty(key string) (PropertyValue, bool)

GetProperty returns the property value and true if it exists.

Parameters:

  • key: The property name to look up

Returns the PropertyValue and true if found, or zero value and false if not found.

Example:

if value, ok := node.GetProperty("name"); ok {
    fmt.Printf("Name: %s\n", value.StringValue())
}

func (*Node) HasLabel

func (n *Node) HasLabel(label string) bool

HasLabel returns true if the node has the given label.

Parameters:

  • label: The label to check for

Returns true if the label exists in the node's Labels slice.

Example:

if node.HasLabel("Person") {
    // Handle person node
}

func (*Node) RemoveLabel

func (n *Node) RemoveLabel(label string)

RemoveLabel removes a label from the node. If the label doesn't exist, the Labels slice remains unchanged.

Parameters:

  • label: The label to remove

Example:

node.RemoveLabel("Temporary")

func (*Node) RemoveProperty

func (n *Node) RemoveProperty(key string)

RemoveProperty removes a property from the node. If the property doesn't exist, this is a no-op.

Parameters:

  • key: The property name to remove

Example:

node.RemoveProperty("temporary")

func (*Node) SetProperty

func (n *Node) SetProperty(key string, value PropertyValue)

SetProperty sets a property value on the node. If the property already exists, it will be overwritten.

Parameters:

  • key: The property name
  • value: The PropertyValue to set

Example:

node.SetProperty("age", graph.NewIntProperty(31))

type PropertyType

type PropertyType string

PropertyType represents the type of a property value.

const (
	PropertyTypeString PropertyType = "string"
	PropertyTypeInt    PropertyType = "int"
	PropertyTypeFloat  PropertyType = "float"
	PropertyTypeBool   PropertyType = "bool"
	PropertyTypeList   PropertyType = "list"
)

type PropertyValue

type PropertyValue struct {
	// String holds the value if this is a string property.
	String *string

	// Int holds the value if this is an integer property.
	Int *int64

	// Float holds the value if this is a float property.
	Float *float64

	// Bool holds the value if this is a boolean property.
	Bool *bool

	// List holds a heterogeneous list of PropertyValue items.
	List []PropertyValue
}

PropertyValue represents a typed property value that can hold string, int, float, bool, or a list of values. It uses a union-style structure where only one field is populated at a time. Use the New*Property constructors to create PropertyValue instances.

PropertyValue supports:

  • String values
  • Integer values (int64)
  • Floating point values (float64)
  • Boolean values
  • List values ([]PropertyValue) — can hold any mix of scalar types

Example:

// Create different types of property values
name := graph.NewStringProperty("Alice")
age := graph.NewIntProperty(30)
tags := graph.NewListProperty([]graph.PropertyValue{
    graph.NewStringProperty("go"),
    graph.NewIntProperty(1),
})

// Check the type
switch name.Type() {
case graph.PropertyTypeString:
    fmt.Println("It's a string")
case graph.PropertyTypeList:
    fmt.Println("It's a list")
}

func NewBoolProperty

func NewBoolProperty(v bool) PropertyValue

NewBoolProperty creates a PropertyValue holding a bool.

Parameters:

  • v: The bool value to store

Returns a PropertyValue containing the boolean.

Example:

prop := graph.NewBoolProperty(true)

func NewFloatProperty

func NewFloatProperty(v float64) PropertyValue

NewFloatProperty creates a PropertyValue holding a float64.

Parameters:

  • v: The float64 value to store

Returns a PropertyValue containing the float.

Example:

prop := graph.NewFloatProperty(3.14)

func NewIntProperty

func NewIntProperty(v int64) PropertyValue

NewIntProperty creates a PropertyValue holding an int64.

Parameters:

  • v: The int64 value to store

Returns a PropertyValue containing the integer.

Example:

prop := graph.NewIntProperty(42)

func NewListProperty added in v0.2.2

func NewListProperty(items []PropertyValue) PropertyValue

NewListProperty creates a PropertyValue holding a list of PropertyValue items. The list can contain any mix of scalar types (string, int, float, bool).

func NewStringProperty

func NewStringProperty(v string) PropertyValue

NewStringProperty creates a PropertyValue holding a string.

Parameters:

  • v: The string value to store

Returns a PropertyValue containing the string.

Example:

prop := graph.NewStringProperty("hello")

func ToPropertyValue

func ToPropertyValue(v interface{}) PropertyValue

ToPropertyValue converts a Go value to a PropertyValue. It supports the following types:

  • string: Stored as PropertyTypeString
  • int, int64: Stored as PropertyTypeInt
  • float64: Stored as PropertyTypeFloat
  • bool: Stored as PropertyTypeBool
  • Other types: Converted to string using fmt.Sprintf

Parameters:

  • v: The value to convert

Returns a PropertyValue containing the converted value.

Example:

// Various conversions
strProp := graph.ToPropertyValue("hello")
intProp := graph.ToPropertyValue(42)
floatProp := graph.ToPropertyValue(3.14)
boolProp := graph.ToPropertyValue(true)

func (PropertyValue) BoolValue

func (p PropertyValue) BoolValue() bool

BoolValue returns the bool value, or false if not a bool type.

Returns the bool value if this PropertyValue holds a boolean, otherwise false.

Example:

prop := graph.NewBoolProperty(true)
fmt.Println(prop.BoolValue()) // Output: true

func (PropertyValue) FloatValue

func (p PropertyValue) FloatValue() float64

FloatValue returns the float value, or 0 if not a float type.

Returns the float64 value if this PropertyValue holds a float, otherwise 0.

Example:

prop := graph.NewFloatProperty(3.14)
fmt.Println(prop.FloatValue()) // Output: 3.14

func (PropertyValue) IntValue

func (p PropertyValue) IntValue() int64

IntValue returns the int value, or 0 if not an int type.

Returns the int64 value if this PropertyValue holds an integer, otherwise 0.

Example:

prop := graph.NewIntProperty(42)
fmt.Println(prop.IntValue()) // Output: 42

func (PropertyValue) InterfaceValue added in v0.2.2

func (p PropertyValue) InterfaceValue() interface{}

InterfaceValue converts a PropertyValue to a Go interface{} value. String returns string, Int returns int (or int64 if out of range), Float returns float64, Bool returns bool, List returns []interface{}.

func (PropertyValue) ListValue added in v0.2.2

func (p PropertyValue) ListValue() []PropertyValue

ListValue returns the list of PropertyValue items, or nil if not a list type.

func (PropertyValue) StringValue

func (p PropertyValue) StringValue() string

StringValue returns the string value, or empty string if not a string type.

Returns the string value if this PropertyValue holds a string, otherwise "".

Example:

prop := graph.NewStringProperty("hello")
fmt.Println(prop.StringValue()) // Output: hello

func (PropertyValue) Type

func (p PropertyValue) Type() PropertyType

Type returns the type of the property value. It checks which field is populated and returns the corresponding type. If no field is populated, it returns PropertyTypeString as a default.

Returns the PropertyType of this value.

Example:

prop := graph.NewIntProperty(42)
fmt.Println(prop.Type()) // Output: int

type Relationship

type Relationship struct {
	// ID is the unique identifier for this relationship.
	ID string

	// StartNodeID is the ID of the node where this relationship originates.
	StartNodeID string

	// EndNodeID is the ID of the node where this relationship points to.
	EndNodeID string

	// Type is the category of this relationship (e.g., "KNOWS", "WORKS_AT").
	Type string

	// Properties are the key-value pairs associated with this relationship.
	// Values are stored as PropertyValue which supports string, int, float, and bool.
	Properties map[string]PropertyValue
}

Relationship represents a directed relationship between two nodes in a graph. Relationships connect nodes and can also have their own properties, allowing you to model complex connections with attributes.

Each relationship has:

  • A unique identifier (ID)
  • A start node ID (where the relationship originates)
  • An end node ID (where the relationship points to)
  • A type that categorizes the relationship
  • Properties that store data as key-value pairs

Relationships are directed, meaning they have a clear direction from start node to end node. For bidirectional relationships, you typically create two relationships or query in both directions.

func NewRelationship

func NewRelationship(startNodeID, endNodeID, relType string, properties map[string]interface{}) *Relationship

NewRelationship creates a new Relationship with the given parameters.

Parameters:

  • startNodeID: The ID of the node where the relationship originates
  • endNodeID: The ID of the node where the relationship points to
  • relType: The type/category of the relationship (e.g., "KNOWS")
  • properties: A map of property names to values. Values can be string, int, int64, float64, or bool. Other types will be converted to strings.

Returns a new Relationship with a generated unique ID.

Example:

rel := graph.NewRelationship(
    alice.ID,    // start node
    bob.ID,      // end node
    "KNOWS",     // relationship type
    map[string]interface{}{
        "since": "2020-01-01",
        "strength": 0.8,
    },
)

func (*Relationship) GetProperty

func (r *Relationship) GetProperty(key string) (PropertyValue, bool)

GetProperty returns the property value and true if it exists.

Parameters:

  • key: The property name to look up

Returns the PropertyValue and true if found, or zero value and false if not found.

Example:

if value, ok := rel.GetProperty("since"); ok {
    fmt.Printf("Relationship started: %s\n", value.StringValue())
}

func (*Relationship) RemoveProperty

func (r *Relationship) RemoveProperty(key string)

RemoveProperty removes a property from the relationship. If the property doesn't exist, this is a no-op.

Parameters:

  • key: The property name to remove

Example:

rel.RemoveProperty("temporary")

func (*Relationship) SetProperty

func (r *Relationship) SetProperty(key string, value PropertyValue)

SetProperty sets a property value on the relationship. If the property already exists, it will be overwritten.

Parameters:

  • key: The property name
  • value: The PropertyValue to set

Example:

rel.SetProperty("strength", graph.NewFloatProperty(0.9))

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL