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 ¶
- func EncodePropertyValue(v PropertyValue) string
- func GenerateID(prefix string) string
- func SetIDCounter(counter uint64)
- type AdjacencyList
- func (adj *AdjacencyList) AddRelationship(m Mutator, rel *Relationship) error
- func (adj *AdjacencyList) GetAllRelated(nodeID string) ([]string, error)
- func (adj *AdjacencyList) GetRelatedNodes(nodeID, relType string, direction Direction) ([]string, error)
- func (adj *AdjacencyList) RemoveRelationship(m Mutator, rel *Relationship) error
- type Direction
- type Index
- func (idx *Index) BuildLabelIndex(m Mutator, node *Node) error
- func (idx *Index) BuildPropertyIndex(m Mutator, node *Node) error
- func (idx *Index) LookupByLabel(label string) ([]string, error)
- func (idx *Index) LookupByProperty(label, propName, propValue string) ([]string, error)
- func (idx *Index) RemoveLabelIndex(m Mutator, node *Node) error
- func (idx *Index) RemovePropertyIndex(m Mutator, node *Node) error
- type Mutator
- type Node
- type PropertyType
- type PropertyValue
- type Relationship
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 ¶
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 ¶
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
type Index ¶
type Index struct {
// contains filtered or unexported fields
}
Index manages label and property indexes for efficient node lookups.
func (*Index) BuildLabelIndex ¶
BuildLabelIndex creates index entries for all labels on a node.
func (*Index) BuildPropertyIndex ¶
BuildPropertyIndex creates index entries for all properties on a node.
func (*Index) LookupByLabel ¶
LookupByLabel returns all node IDs that have the given label.
func (*Index) LookupByProperty ¶
LookupByProperty returns all node IDs that have the given label and property value.
func (*Index) RemoveLabelIndex ¶
RemoveLabelIndex removes index entries for all labels on a node.
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 ¶
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 ¶
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 ¶
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 ¶
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" )
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
}
PropertyValue represents a typed property value that can hold string, int, float, or bool. 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
Example:
// Create different types of property values
name := graph.NewStringProperty("Alice")
age := graph.NewIntProperty(30)
balance := graph.NewFloatProperty(1234.56)
active := graph.NewBoolProperty(true)
// Check the type
switch name.Type() {
case graph.PropertyTypeString:
fmt.Println("It's a string")
case graph.PropertyTypeInt:
fmt.Println("It's an integer")
}
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 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) 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))