golang轻量级ArangoDB数据库驱动插件库arangolite的使用

Golang轻量级ArangoDB数据库驱动插件库arangolite的使用

简介

Arangolite是一个轻量级的ArangoDB Go语言驱动库,专注于纯AQL查询。如果你需要更类似ORM的体验,可以参考AranGO项目。

安装

要安装Arangolite:

go get -u github.com/solher/arangolite/v2

基本用法

下面是一个完整的使用示例:

package main

import (
  "context"
  "fmt"
  "log"

  "github.com/solher/arangolite/v2"
  "github.com/solher/arangolite/v2/requests"
)

// 定义文档结构
type Node struct {
  arangolite.Document
}

func main() {
  ctx := context.Background()

  // 声明数据库配置
  db := arangolite.NewDatabase(
    arangolite.OptEndpoint("http://localhost:8529"),
    arangolite.OptBasicAuth("root", "rootPassword"),
    arangolite.OptDatabaseName("_system"),
  )

  // Connect方法做两件事:
  // 1. 如果需要则初始化连接(JWT认证)
  // 2. 检查数据库连接性
  if err := db.Connect(ctx); err != nil {
    log.Fatal(err)
  }

  // 创建一个新数据库
  err := db.Run(ctx, nil, &requests.CreateDatabase{
    Name: "testDB",
    Users: []map[string]interface{}{
      {"username": "root", "passwd": "rootPassword"},
      {"username": "user", "passwd": "password"},
    },
  })
  if err != nil {
    log.Fatal(err)
  }

  // 使用新创建的用户登录新数据库
  db.Options(
    arangolite.OptBasicAuth("user", "password"),
    arangolite.OptDatabaseName("testDB"),
  )

  // 创建一个"nodes"集合
  if err := db.Run(ctx, nil, &requests.CreateCollection{Name: "nodes"}); err != nil {
    log.Fatal(err)
  }

  // 声明一个带选项和绑定参数的AQL查询
  key := "48765564346"
  r := requests.NewAQL(`
    FOR n
    IN nodes
    FILTER n._key == @key
    RETURN n
  `, key).
    Bind("key", key).
    Cache(true).
    BatchSize(500) // 缓存功能在ArangoDB 2.7之前不可用

  // Run方法返回游标中所有页面的查询结果
  // 并将其解组到给定的结构中
  // 取消上下文会取消每个正在运行的请求
  nodes := []Node{}
  if err := db.Run(ctx, &nodes, r); err != nil {
    log.Fatal(err)
  }

  // Send方法给用户更多控制权,不跟踪游标
  // 它返回一个原始结果对象
  result, err := db.Send(ctx, r)
  if err != nil {
    log.Fatal(err)
  }
  nodes = []Node{}
  result.UnmarshalResult(&nodes)

  // 如果有更多结果,继续获取
  for result.HasMore() {
    result, err = db.Send(ctx, &requests.FollowCursor{Cursor: result.Cursor()})
    if err != nil {
      log.Fatal(err)
    }
    tmp := []Node{}
    result.UnmarshalResult(&tmp)

    nodes = append(nodes, tmp...)
  }

  fmt.Println(nodes)
}

文档和边

Arangolite提供了基本的文档和边结构:

// Document表示基本的ArangoDB文档
type Document struct {
  // 文档句柄。格式:':collection/:key'
  ID string `json:"_id,omitempty"`
  // 文档的修订令牌。每次更新时更改
  Rev string `json:"_rev,omitempty"`
  // 文档的唯一键
  Key string `json:"_key,omitempty"`
}

// Edge表示基本的ArangoDB边
type Edge struct {
  Document
  // 引用另一个文档。格式:':collection/:key'
  From string `json:"_from,omitempty"`
  // 引用另一个文档。格式:':collection/:key'
  To string `json:"_to,omitempty"`
}

事务

Arangolite提供了对Javascript ArangoDB事务的抽象层。

使用示例

t := requests.NewTransaction([]string{"nodes"}, nil).
  AddAQL("nodes", `
    FOR n
    IN nodes
    RETURN n
`).
  AddAQL("ids", `
    FOR n
    IN {{.nodes}}
    RETURN n._id
`).
  Return("ids")

ids := []string{}
if err := db.Run(ctx, ids, t); err != nil {
  log.Fatal(err)
}

图操作

AQL可用于查询图数据。要管理图,Arangolite提供了一些特定的请求:

  • CreateGraph 创建图
  • ListGraphs 列出可用图
  • GetGraph 获取现有图
  • DropGraph 删除图

使用示例

// 检查图是否存在
if err := db.Run(ctx, nil, &requests.GetGraph{Name: "graphName"}); err != nil {
  switch {
  case arangolite.IsErrNotFound(err):
    // 如果图不存在,创建一个新图
    edgeDefinitions := []requests.EdgeDefinition{
      {
        Collection: "edgeCollectionName",
        From:       []string{"firstCollectionName"},
        To:         []string{"secondCollectionName"},
      },
    }
    db.Run(ctx, nil, &requests.CreateGraph{Name: "graphName", EdgeDefinitions: edgeDefinitions})
  default:
    log.Fatal(err)
  }
}

// 列出现有图
list := &requests.GraphList{}
db.Run(ctx, list, &requests.ListGraphs{})
fmt.Printf("Graph list: %v\n", list)

// 销毁刚创建的图和相关集合
db.Run(ctx, nil, &requests.DropGraph{Name: "graphName", DropCollections: true})

错误处理

可以使用提供的测试器处理错误:

// IsErrInvalidRequest 当数据库返回400时返回true
func IsErrInvalidRequest(err error) bool {
  return HasStatusCode(err, 400)
}

// IsErrUnauthorized 当数据库返回401时返回true
func IsErrUnauthorized(err error) bool {
  return HasStatusCode(err, 401)
}

// IsErrForbidden 当数据库返回403时返回true
func IsErrForbidden(err error) bool {
  return HasStatusCode(err, 403)
}

// IsErrUnique 当错误号为1210(ERROR_ARANGO_UNIQUE_CONSTRAINT_VIOLATED)时返回true
func IsErrUnique(err error) bool {
  return HasErrorNum(err, 1210)
}

// IsErrNotFound 当数据库返回404或错误号为以下值时返回true:
// 1202 - ERROR_ARANGO_DOCUMENT_NOT_FOUND
// 1203 - ERROR_ARANGO_COLLECTION_NOT_FOUND
func IsErrNotFound(err error) bool {
  return HasStatusCode(err, 404) || HasErrorNum(err, 1202, 1203)
}

或者通过HasStatusCodeHasErrorNum方法手动处理。

贡献

目前,Arangolite中实现的ArangoDB HTTP API方法很少。幸运的是,通过实现Runnable接口可以很容易地添加你自己的方法。然后你可以使用常规的RunSend方法。

// Runnable定义了可由Run和Send方法运行的请求
// Runnable库位于'requests'包中
type Runnable interface {
  // 请求体
  Generate() []byte
  // 发送请求的路径
  Path() string
  // 使用的HTTP方法
  Method() string
}

当你实现一些新功能时,请提交pull request,这样每个人都可以使用它。

许可证

MIT


更多关于golang轻量级ArangoDB数据库驱动插件库arangolite的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang轻量级ArangoDB数据库驱动插件库arangolite的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Arangolite - Golang轻量级ArangoDB驱动使用指南

Arangolite是一个轻量级的Golang ArangoDB驱动,提供了简单直接的API来与ArangoDB交互。下面我将详细介绍其使用方法。

安装

首先安装arangolite包:

go get github.com/solher/arangolite

基本使用

1. 创建连接

package main

import (
	"log"
	
	"github.com/solher/arangolite"
)

func main() {
	// 创建数据库连接
	db := arangolite.New().
		LoggerOptions(false, false, false). // 禁用日志
		Connect("http://localhost:8529", "testDB", "root", "password")
	
	// 测试连接
	if err := db.Test(); err != nil {
		log.Fatal("连接失败:", err)
	}
	log.Println("成功连接到ArangoDB")
}

2. 执行AQL查询

// 查询示例
type User struct {
	arangolite.Document // 内嵌Document提供_id, _key等字段
	Name string `json:"name"`
	Age  int    `json:"age"`
}

func queryUsers(db *arangolite.DB) {
	// 创建查询
	query := arangolite.NewQuery(`
		FOR u IN users
		FILTER u.age > @age
		RETURN u
	`).Bind("age", 20)
	
	// 执行查询
	var users []User
	if err := db.Run(query, &users); err != nil {
		log.Fatal("查询失败:", err)
	}
	
	log.Printf("找到%d个用户:", len(users))
	for _, u := range users {
		log.Printf("ID: %s, 名称: %s, 年龄: %d", u.ID, u.Name, u.Age)
	}
}

3. 集合操作

// 创建集合
func createCollection(db *arangolite.DB) {
	// 创建users集合
	_, err := db.Run(&arangolite.CreateCollection{
		Name: "users",
	})
	if err != nil {
		log.Fatal("创建集合失败:", err)
	}
	log.Println("成功创建users集合")
}

// 添加文档
func addUser(db *arangolite.DB) {
	user := User{
		Name: "张三",
		Age:  25,
	}
	
	// 插入文档
	_, err := db.Run(&arangolite.Insert{
		Collection: "users",
		Document:   &user,
	})
	if err != nil {
		log.Fatal("插入文档失败:", err)
	}
	log.Printf("成功添加用户: %s (ID: %s)", user.Name, user.ID)
}

4. 事务支持

func transactionExample(db *arangolite.DB) {
	// 定义事务
	transaction := arangolite.NewTransaction([]string{"users"}, nil).
		AddQuery("updateUser", `
			FOR u IN users
			FILTER u._key == @key
			UPDATE u WITH { age: @newAge } IN users
			RETURN NEW
		`).Bind("key", "123").Bind("newAge", 30)
	
	// 执行事务
	var result []User
	if err := db.Run(transaction, &result); err != nil {
		log.Fatal("事务执行失败:", err)
	}
	
	log.Println("事务执行成功,更新后的用户:", result)
}

5. 图操作

// 创建图
func createGraph(db *arangolite.DB) {
	_, err := db.Run(&arangolite.CreateGraph{
		Name: "social",
		EdgeDefinitions: []arangolite.EdgeDefinition{
			{
				Collection: "friends",
				From:       []string{"users"},
				To:         []string{"users"},
			},
		},
	})
	if err != nil {
		log.Fatal("创建图失败:", err)
	}
	log.Println("成功创建social图")
}

// 图查询
func graphQuery(db *arangolite.DB) {
	query := arangolite.NewQuery(`
		FOR v, e, p IN 1..2 OUTBOUND @start GRAPH 'social'
		RETURN { vertex: v, edge: e, path: p }
	`).Bind("start", "users/123")
	
	var results []map[string]interface{}
	if err := db.Run(query, &results); err != nil {
		log.Fatal("图查询失败:", err)
	}
	
	log.Println("图查询结果:", results)
}

高级特性

批量操作

func batchOperations(db *arangolite.DB) {
	// 创建批量操作
	batch := arangolite.NewBatch()
	
	// 添加多个操作
	batch.AddQuery("getUsers", `
		FOR u IN users
		LIMIT 10
		RETURN u
	`)
	
	batch.AddQuery("countUsers", `
		RETURN LENGTH(users)
	`)
	
	// 执行批量操作
	var results struct {
		GetUsers  []User `json:"getUsers"`
		CountUsers int   `json:"countUsers"`
	}
	
	if err := db.Run(batch, &results); err != nil {
		log.Fatal("批量操作失败:", err)
	}
	
	log.Printf("获取到%d个用户,总数: %d", len(results.GetUsers), results.CountUsers)
}

性能优化建议

  1. 使用连接池:
db := arangolite.New().
	ConnectionPool(10, 20). // 最小10,最大20连接
	Connect(...)
  1. 对于大量数据,使用游标:
query := arangolite.NewQuery(...).BatchSize(1000) // 每批1000条
  1. 使用预编译查询提高重复查询性能

总结

Arangolite提供了简洁的API来操作ArangoDB,主要特点包括:

  • 轻量级,无外部依赖
  • 支持AQL查询、事务、图操作
  • 简单的文档映射
  • 批量操作支持

相比官方驱动,它更加轻量且易于使用,适合不需要全部ArangoDB功能的项目。对于需要完整功能的项目,可以考虑官方Go驱动。

希望这个指南能帮助你快速上手使用Arangolite!

回到顶部