falkordb-go is a Golang client for the FalkorDB database.
- Lightweight client with simple Query/ROQuery APIs.
- Parses nodes, edges, paths, arrays, maps, points, and vectors into Go types.
- Exposes query statistics plus PrettyPrint for quick inspection.
- Supports single instance, cluster, sentinel discovery, and TLS via URL schemes.
- Full
context.Contextsupport via*Contextmethods. trunkis the primary, up-to-date branch.
- Start a local FalkorDB (standalone):
docker compose -f docker-compose.standalone.yml up -d
- Add the client to your module:
go get github.com/snowmerak/falkordb-go
- Run a minimal query:
package main
import (
"context"
"log"
"github.com/snowmerak/falkordb-go"
"github.com/snowmerak/falkordb-go/graph"
)
func main() {
ctx := context.Background()
db, err := falkordb.FromURL("falkor://0.0.0.0:6379")
if err != nil {
log.Fatal(err)
}
g := db.SelectGraph("social")
_, err = g.QueryContext(ctx, "CREATE (:Person {name:'John Doe', age:33})", nil, nil)
if err != nil {
log.Fatal(err)
}
opts := graph.NewQueryOptions().SetTimeout(10) // ms timeout
res, err := g.QueryContext(ctx, "MATCH (p:Person) RETURN p.name, p.age", nil, opts)
if err != nil {
log.Fatal(err)
}
res.PrettyPrint()
}All methods without Context suffix are deprecated and annotated with //go:fix inline. Run go fix ./... to automatically migrate:
-res, err := g.Query("MATCH (n) RETURN n", nil, nil)
+res, err := g.QueryContext(context.Background(), "MATCH (n) RETURN n", nil, nil)The old methods remain available for backward compatibility but will delegate to context.Background() internally.
The complete API is documented on pkg.go.dev.
- Query vs ROQuery
res, err := g.QueryContext(ctx, "MATCH (p:Person) RETURN p.name", nil, nil)
roRes, err := g.ROQueryContext(ctx, "MATCH (p:Person) RETURN p.name", nil, nil)- Iterating results
for res.Next() {
r := res.Record()
name := r.GetByIndex(0)
log.Printf("name=%v", name)
}- With timeouts (milliseconds)
opts := graph.NewQueryOptions().SetTimeout(5)
res, err := g.QueryContext(ctx, "UNWIND range(0, 1000000) AS v RETURN v", nil, opts)- Read-only client
db, err := falkordb.NewReadOnly(&falkordb.ConnectionOption{Addr: "0.0.0.0:6379"})
if err != nil { log.Fatal(err) }
g := db.SelectGraph("social")
// This will error because the graph is read-only
_, err = g.QueryContext(ctx, "CREATE (:X)", nil, nil)
// RO queries are allowed
res, err := g.ROQueryContext(ctx, "MATCH (n) RETURN n", nil, nil)- Pipelined batch queries
reqs := []graph.QueryRequest{
{
Query: "MATCH (p:Person) RETURN p",
Options: graph.NewQueryOptions().SetTimeout(50),
},
{
Command: graph.CmdROQuery,
Query: "MATCH (c:Country {name:$name}) RETURN c",
Params: map[string]interface{}{"name": "Japan"},
},
}
batch, err := g.PipelineContext(ctx, reqs)
if err != nil {
log.Fatal(err)
}
// batch[0], batch[1] are ordered resultsoptions := graph.NewQueryOptions().SetTimeout(10) // 10-millisecond timeout
res, err := g.QueryContext(ctx, "MATCH (src {name: 'John Doe'})-[*]->(dest) RETURN dest", nil, options)lines, err := g.ProfileContext(ctx, "MATCH (p:Person) RETURN p", nil, nil)
// lines is []string with execution planerr := db.CopyGraphContext(ctx, "social", "social_backup")mem, err := g.MemoryUsageContext(ctx, -1) // -1 for default sample count// Create a UNIQUE constraint (requires an existing index)
err := db.CreateConstraintContext(ctx, "social", "UNIQUE", "NODE", "Person", []string{"name"})
// Create a MANDATORY constraint
err := db.CreateConstraintContext(ctx, "social", "MANDATORY", "NODE", "Person", []string{"age"})
// Drop a constraint
err := db.DropConstraintContext(ctx, "social", "MANDATORY", "NODE", "Person", []string{"age"})entries, err := g.SlowLogContext(ctx)
for _, e := range entries {
log.Printf("ts=%s cmd=%s query=%s duration=%s", e.Timestamp, e.Command, e.Query, e.Duration)
}
err = g.SlowLogResetContext(ctx)info, err := db.InfoContext(ctx, falkordb.InfoAll) // or InfoRunningQueries, InfoWaitingQueries
log.Printf("Running: %d, Waiting: %d", len(info.RunningQueries), len(info.WaitingQueries))err := db.LoadUDFContext(ctx, "mylib", "function my_func(a, b) { return a + b }")
err := db.LoadUDFFromFileContext(ctx, "mylib", "/path/to/lib.js")
// Load and replace if exists
err := db.LoadUDFReplaceContext(ctx, "mylib", "function my_func(a, b) { return a * b }")libs, err := db.ListUDFContext(ctx)
libs, err := db.ListUDFContext(ctx, falkordb.WithUDFLibrary("mylib"))
libs, err := db.ListUDFContext(ctx, falkordb.WithUDFCode())err := db.DeleteUDFContext(ctx, "mylib")
err := db.FlushUDFsContext(ctx)| FalkorDB Type | Go Type |
|---|---|
| Node | domain.Node |
| Edge | domain.Edge |
| Path | domain.Path |
| Map | map[string]interface{} |
| Array | []interface{} |
| Integer | int64 |
| Float | float64 |
| String | string |
| Boolean | bool |
| Null | nil |
| Point | map[string]interface{} |
| Vector | []float32 |
| Date / LocalDateTime | time.Time |
| LocalTime | time.Time |
| Duration | time.Duration |
- Single instance:
falkordb.New(&falkordb.ConnectionOption{Addr: "0.0.0.0:6379"}) - Cluster:
falkordb.NewCluster(&falkordb.ConnectionClusterOption{Addrs: []string{"0.0.0.0:6379"}}) - URL-based (sentinel/TLS aware):
falkordb.FromURL("falkor://host:port")orfalkors://for TLS.
task test
# or
go test ./...
The tests expect a FalkorDB server at localhost:6379 (or FALKORDB_ADDR). Task automation is in Taskfile.yml.
falkordb-go is distributed under the BSD3 license - see LICENSE