golang Riak KV数据库驱动插件库goriak的使用
golang Riak KV数据库驱动插件库goriak的使用
goriak是一个封装了riak-go-client的库,使开发者能更简单友好地使用Riak KV数据库。
安装
作为Go模块(需要Go 1.11或更高版本):
go get github.com/zegl/goriak/v3@v3.2.3
作为Go包:
go get -u gopkg.in/zegl/goriak.v3
Maps (Riak数据类型)
goriak的主要特性是能自动将Go类型编组/解组到Riak数据类型中。
Set (Riak数据类型)
在下面的示例中,Name
将作为register保存,Aliases
将作为set保存。
type User struct {
Name string
Aliases []string
}
user := User {
Name: "Foo",
Alises: []string{"Foo", "Bar"},
}
goriak.Bucket("bucket-name", "bucket-type").Set(user).Key("key").Run(c)
标签
可以使用结构体标签来改变字段名称或忽略字段。
type User struct {
Name string `goriak:"-"` // 忽略字段
Aliases []string `goriak:"aliases"` // 在Riak KV中保存为"aliases"
}
Get (Riak数据类型)
之后可以整体获取map:
var res User
goriak.Bucket("bucket-name", "bucket-type").Get("key", &res).Run(c)
支持的Go类型
Go类型 | Riak类型 |
---|---|
struct |
map |
string |
register |
[n]byte |
register |
[]byte |
register |
[]slice |
set |
[][]byte |
set |
map |
map |
time.Time |
register |
int [1] | register |
1: 支持所有有符号和无符号整数类型。
Golang map类型
支持的键类型: 所有整数类型, string
。
支持的值类型: string
, []byte
。
辅助类型
有些操作使用默认的Go类型和MapOperations
会过于复杂。因此goriak包含了Counter
、Set
、Flag
和Register
类型。这些类型将帮助你执行诸如增加一个值或添加/删除项目等操作。
计数器
Riak计数器通过特殊的goriak.Counter
类型支持。
示例:
type Article struct {
Title string
Views *goriak.Counter
}
// 获取对象
var article Article
goriak.Bucket("articles", "map").Get("1-hello-world", &article).Run(con)
// 增加1次浏览
err := article.Views.Increase(1).Exec(con)
// 检查错误
Counter.Exec(con)
会向Riak发送一个轻量级请求,只有计数器会被更新。你也可以使用SetMap()
保存计数器的更改,这在你想同时更改多个计数器时很有用。
集合
你可以选择使用goriak.Set
来帮助你处理集合相关操作,如添加和删除项目。goriak.Set
还支持向Riak发送增量操作,这样你就不需要自己构建这个功能。
示例:
type Article struct {
Title string
Tags *goriak.Set
}
// 获取对象
var article Article
goriak.Bucket("articles", "map").Get("1-hello-world", &article).Run(con)
// 添加标签"animals"
err := article.Tags.AddString("animals").Exec(con)
// 检查错误
值
可以使用SetJSON()
和GetJSON()
自动进行JSON编组/解组。还有SetRaw()
和GetRaw()
直接处理[]byte
。
JSON
// 设置对象
goriak.Bucket("bucket-name", "bucket-type").SetJSON(obj).Key("key").Run(con)
// 获取对象
goriak.Bucket("bucket-name", "bucket-type").GetJSON("key", &obj).Run(con)
MapOperation
有时候你需要对Riak数据值执行原始的MapOperations。有些操作,如RemoveFromSet
需要一个Context来执行操作。可以通过设置一个特殊的context类型从Get
中获取Context。
type ourType struct {
Aliases []string
// 如果提供了goriakcontext标签,Riak的context会被添加
Context []byte `goriak:"goriakcontext"`
}
// ... GetMap()
// 与github.com/basho/riak-go-client中的MapOperation一起工作
operation := goriak.NewMapOperation()
operation.AddToSet("Aliases", []byte("Baz"))
goriak.MapOperation("bucket-name", "bucket-type", "key", operation, val.Context)
二级索引
你可以使用结构体标签通过SetJSON()
自动设置二级索引。支持字符串和所有有符号整数类型,包括切片形式。
type User struct {
Name string `goriakindex:"nameindex_bin"`
Aliases []string
}
索引也可以在切片中使用。如果使用切片,切片中的每个值都会被添加到索引中。
type User struct {
Aliases []string `goriakindex:"aliasesindex_bin"`
}
下次保存时索引会被更新。
KeysInIndex
可以使用KeysInIndex
获取特定索引中的键。
callback := func(item goriak.SecondaryIndexQueryResult) {
// 使用item
}
goriak.Bucket("bucket-name", "bucket-type").
KeysInIndex("nameindex_bin", "Value", callback).
Run(con)
AddToIndex
另一种设置二级索引的方法是使用AddToIndex()
。
goriak.Bucket("bucket-name", "bucket-type").
SetRaw(data).
AddToIndex("indexname_bin", "value").
Run(con)
更多关于golang Riak KV数据库驱动插件库goriak的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang Riak KV数据库驱动插件库goriak的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang Riak KV 数据库驱动插件库 goriak 使用指南
简介
goriak 是一个用于连接和操作 Riak KV 数据库的 Go 语言客户端库。它提供了简单易用的 API 来与 Riak 集群交互,支持基本的 CRUD 操作以及一些高级功能。
安装
使用 go get 安装 goriak:
go get github.com/zegl/goriak/v3
基本使用
1. 连接 Riak
package main
import (
"context"
"fmt"
"log"
"github.com/zegl/goriak/v3"
)
func main() {
// 创建连接
conn, err := goriak.Connect(goriak.ConnectOpts{
Address: "127.0.0.1", // Riak 服务器地址
Port: 8087, // PB 端口
})
if err != nil {
log.Fatal(err)
}
defer conn.Close()
// 使用连接进行操作...
}
2. 基本 CRUD 操作
存储数据
type User struct {
Name string
Age int
}
func storeData(conn *goriak.Session) {
user := User{
Name: "John Doe",
Age: 30,
}
// 存储数据到 bucket "users",key 为 "user1"
_, err := goriak.Bucket("users", "default").Set(user).Key("user1").Run(conn)
if err != nil {
log.Fatal(err)
}
}
获取数据
func getData(conn *goriak.Session) {
var user User
// 从 bucket "users" 获取 key 为 "user1" 的数据
_, err := goriak.Bucket("users", "default").Get("user1", &user).Run(conn)
if err != nil {
log.Fatal(err)
}
fmt.Printf("User: %+v\n", user)
}
更新数据
func updateData(conn *goriak.Session) {
var user User
// 先获取当前数据
_, err := goriak.Bucket("users", "default").Get("user1", &user).Run(conn)
if err != nil {
log.Fatal(err)
}
// 修改数据
user.Age = 31
// 更新存储
_, err = goriak.Bucket("users", "default").Set(user).Key("user1").Run(conn)
if err != nil {
log.Fatal(err)
}
}
删除数据
func deleteData(conn *goriak.Session) {
// 删除 key 为 "user1" 的数据
_, err := goriak.Bucket("users", "default").Delete("user1").Run(conn)
if err != nil {
log.Fatal(err)
}
}
3. 高级功能
使用二级索引 (2i)
func useSecondaryIndex(conn *goriak.Session) {
// 存储带有索引的数据
user1 := User{Name: "Alice", Age: 25}
_, err := goriak.Bucket("users", "default").
Set(user1).
Key("alice").
AddIndex("age_int", 25). // 添加整数索引
Run(conn)
if err != nil {
log.Fatal(err)
}
user2 := User{Name: "Bob", Age: 30}
_, err = goriak.Bucket("users", "default").
Set(user2).
Key("bob").
AddIndex("age_int", 30).
Run(conn)
if err != nil {
log.Fatal(err)
}
// 查询年龄在 20-30 之间的用户
var results []User
_, err = goriak.Bucket("users", "default").
IndexQuery("age_int", 20, 30, &results).
Run(conn)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Users aged 20-30: %+v\n", results)
}
使用计数器
func useCounter(conn *goriak.Session) {
// 创建或获取计数器
counter := goriak.Bucket("counters", "default").Counter("page_views")
// 增加计数器值
_, err := counter.Increment(5).Run(conn) // 增加5
if err != nil {
log.Fatal(err)
}
// 获取当前值
val, err := counter.Value().Run(conn)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Current counter value: %d\n", val)
}
使用 MapReduce
func useMapReduce(conn *goriak.Session) {
// 创建 MapReduce 查询
query := goriak.NewMapReduceQuery().
Bucket("users").
Map("function(v) { return [JSON.parse(v.values[0].data).Age]; }").
Reduce("function(v) { return [v.reduce(function(a, b) { return a + b; })]; }")
// 执行查询
var result []int
_, err := query.Run(conn, &result)
if err != nil {
log.Fatal(err)
}
if len(result) > 0 {
fmt.Printf("Total age sum: %d\n", result[0])
}
}
最佳实践
-
连接池管理:goriak 内部维护了连接池,不需要手动管理多个连接。
-
错误处理:始终检查返回的错误,Riak 操作可能会因为网络问题或集群状态而失败。
-
上下文使用:支持 context 用于超时和取消操作:
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
_, err := goriak.Bucket("users", "default").Get("user1", &user).WithContext(ctx).Run(conn)
-
批量操作:对于大量数据操作,考虑使用批量接口提高性能。
-
数据类型选择:Riak 适合存储非结构化或半结构化数据,复杂查询不是它的强项。
总结
goriak 提供了简单直观的 API 来与 Riak KV 数据库交互,支持基本 CRUD 操作、二级索引、计数器等高级功能。通过合理使用这些功能,可以构建高性能、分布式的数据存储解决方案。