golang CouchDB和PouchDB数据库客户端插件库Kivik的使用

Golang CouchDB和PouchDB数据库客户端插件库Kivik的使用

Kivik是一个为CouchDB或类似CouchDB的数据库提供通用接口的Go语言包。

安装

使用以下命令安装Kivik:

go get -u github.com/go-kivik/kivik/v4

Kivik需要与数据库驱动一起使用。官方支持的驱动包括:

  • CouchDB: github.com/go-kivik/kivik/v4/couchdb
  • PouchDB: github.com/go-kivik/kivik/v4/pouchdb (需要GopherJS)
  • MockDB: github.com/go-kivik/kivik/v4/mockdb

示例代码

基本使用示例

package main

import (
    "context"
    "fmt"

    kivik "github.com/go-kivik/kivik/v4"
    _ "github.com/go-kivik/kivik/v4/couchdb" // 导入CouchDB驱动
)

func main() {
    // 创建CouchDB客户端
    client, err := kivik.New("couch", "http://localhost:5984/")
    if err != nil {
        panic(err)
    }

    // 选择数据库
    db := client.DB("animals")

    // 创建文档
    doc := map[string]interface{}{
        "_id":      "cow",
        "feet":     4,
        "greeting": "moo",
    }

    // 插入文档
    rev, err := db.Put(context.TODO(), "cow", doc)
    if err != nil {
        panic(err)
    }
    fmt.Printf("Cow inserted with revision %s\n", rev)
}

查询文档示例

package main

import (
    "context"
    "fmt"

    kivik "github.com/go-kivik/kivik/v4"
    _ "github.com/go-kivik/kivik/v4/couchdb"
)

func main() {
    client, err := kivik.New("couch", "http://localhost:5984/")
    if err != nil {
        panic(err)
    }

    db := client.DB("animals")

    // 获取文档
    row := db.Get(context.TODO(), "cow")
    if row.Err() != nil {
        panic(row.Err())
    }

    var doc map[string]interface{}
    if err := row.ScanDoc(&doc); err != nil {
        panic(err)
    }

    fmt.Printf("Document: %+v\n", doc)
}

使用PouchDB示例

package main

import (
    "context"
    "fmt"

    kivik "github.com/go-kivik/kivik/v4"
    _ "github.com/go-kivik/kivik/v4/pouchdb" // 导入PouchDB驱动
)

func main() {
    // 创建PouchDB客户端
    client, err := kivik.New("pouch", "mydb")
    if err != nil {
        panic(err)
    }

    db := client.DB("mydb")

    // 创建文档
    doc := map[string]interface{}{
        "_id":      "dog",
        "feet":     4,
        "greeting": "woof",
    }

    // 插入文档
    rev, err := db.Put(context.TODO(), "dog", doc)
    if err != nil {
        panic(err)
    }
    fmt.Printf("Dog inserted with revision %s\n", rev)
}

特性

Kivik的设计目标包括:

  1. 为各种类似CouchDB的数据库提供通用API
  2. 支持CouchDB 1.6、2.x、3.x及未来版本,以及PouchDB
  3. 尽可能符合Go语言的惯用法
  4. 采用Apache许可证开源
  5. 分离基础数据库驱动实现与用户级类型和便利方法

版本兼容性

  • Go: Kivik 4.x要求Go 1.17或更高版本
  • CouchDB: 支持所有2.x及以上稳定版本
  • PouchDB: 支持8.0.0及以上稳定版本

Kivik 4.x是稳定的,适合生产环境使用。


更多关于golang CouchDB和PouchDB数据库客户端插件库Kivik的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang CouchDB和PouchDB数据库客户端插件库Kivik的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Kivik:Golang中的CouchDB和PouchDB客户端库

Kivik是一个功能强大的Golang库,用于与CouchDB和PouchDB数据库交互。它提供了简洁的API,支持CouchDB 2.x+和PouchDB的所有主要功能。

安装Kivik

go get github.com/go-kivik/kivik/v4

基本用法

1. 连接CouchDB

package main

import (
	"context"
	"fmt"
	"log"

	"github.com/go-kivik/kivik/v4"
	_ "github.com/go-kivik/couchdb/v4" // CouchDB驱动
)

func main() {
	client, err := kivik.New("couch", "http://localhost:5984")
	if err != nil {
		log.Fatal(err)
	}

	// 验证连接
	version, err := client.Version(context.TODO())
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("Connected to CouchDB version %s\n", version.Version)
}

2. 数据库操作

// 创建/获取数据库
db := client.DB(context.TODO(), "mydb")

// 检查数据库是否存在
exists, err := db.Exists(context.TODO())
if err != nil {
	log.Fatal(err)
}
if !exists {
	// 创建数据库
	if err := client.CreateDB(context.TODO(), "mydb"); err != nil {
		log.Fatal(err)
	}
}

// 删除数据库
if err := client.DestroyDB(context.TODO(), "mydb"); err != nil {
	log.Fatal(err)
}

3. 文档CRUD操作

// 创建文档
doc := map[string]interface{}{
	"_id":      "doc1",
	"title":    "My Document",
	"content":  "This is a test document",
	"tags":     []string{"test", "example"},
	"created":  time.Now(),
}

rev, err := db.Put(context.TODO(), "doc1", doc)
if err != nil {
	log.Fatal(err)
}
fmt.Printf("Document created with revision %s\n", rev)

// 读取文档
row := db.Get(context.TODO(), "doc1")
var docRead map[string]interface{}
if err := row.ScanDoc(&docRead); err != nil {
	log.Fatal(err)
}
fmt.Printf("Document: %+v\n", docRead)

// 更新文档
docRead["content"] = "Updated content"
newRev, err := db.Put(context.TODO(), "doc1", docRead)
if err != nil {
	log.Fatal(err)
}

// 删除文档
if _, err := db.Delete(context.TODO(), "doc1", newRev); err != nil {
	log.Fatal(err)
}

4. 查询操作

// 创建索引
index := map[string]interface{}{
	"index": map[string]interface{}{
		"fields": []string{"title"},
	},
	"name": "title-index",
	"type": "json",
}
if _, err := db.CreateIndex(context.TODO(), "", "", index); err != nil {
	log.Fatal(err)
}

// 执行查询
query := map[string]interface{}{
	"selector": map[string]interface{}{
		"title": map[string]interface{}{
			"$eq": "My Document",
		},
	},
}

rows, err := db.Find(context.TODO(), query)
if err != nil {
	log.Fatal(err)
}

for rows.Next() {
	var result map[string]interface{}
	if err := rows.ScanDoc(&result); err != nil {
		log.Fatal(err)
	}
	fmt.Printf("Found document: %+v\n", result)
}

if err := rows.Err(); err != nil {
	log.Fatal(err)
}

5. 使用PouchDB

Kivik也支持PouchDB,用法类似:

import (
	_ "github.com/go-kivik/pouchdb/v4" // PouchDB驱动
)

func main() {
	client, err := kivik.New("pouch", "")
	if err != nil {
		log.Fatal(err)
	}
	
	// 创建内存数据库
	db := client.DB(context.TODO(), "mydb")
	
	// 其他操作与CouchDB相同...
}

高级特性

1. 批量操作

docs := []interface{}{
	map[string]interface{}{
		"_id":   "doc2",
		"title": "Second doc",
	},
	map[string]interface{}{
		"_id":   "doc3",
		"title": "Third doc",
	},
}

results, err := db.BulkDocs(context.TODO(), docs)
if err != nil {
	log.Fatal(err)
}

for _, result := range results {
	if result.Error != nil {
		fmt.Printf("Error with doc %s: %v\n", result.ID, result.Error)
		continue
	}
	fmt.Printf("Successfully created doc %s with rev %s\n", result.ID, result.Rev)
}

2. 附件操作

// 添加附件
attachment := &kivik.Attachment{
	Filename:    "test.txt",
	ContentType: "text/plain",
	Content:     strings.NewReader("This is a test attachment"),
}

rev, err = db.PutAttachment(context.TODO(), "doc1", rev, attachment)
if err != nil {
	log.Fatal(err)
}

// 获取附件
att, err := db.GetAttachment(context.TODO(), "doc1", rev, "test.txt")
if err != nil {
	log.Fatal(err)
}
defer att.Content.Close()

data, err := ioutil.ReadAll(att.Content)
if err != nil {
	log.Fatal(err)
}
fmt.Printf("Attachment content: %s\n", string(data))

3. 变更订阅

changes, err := db.Changes(context.TODO())
if err != nil {
	log.Fatal(err)
}

for changes.Next() {
	var change struct {
		ID      string `json:"id"`
		Deleted bool   `json:"deleted"`
		Changes []struct {
			Rev string `json:"rev"`
		} `json:"changes"`
	}
	
	if err := changes.ScanDoc(&change); err != nil {
		log.Fatal(err)
	}
	
	fmt.Printf("Change detected: ID=%s, Deleted=%v, Rev=%s\n", 
		change.ID, change.Deleted, change.Changes[0].Rev)
}

if err := changes.Err(); err != nil {
	log.Fatal(err)
}

最佳实践

  1. 总是检查错误
  2. 使用context进行超时和取消控制
  3. 对于生产环境,考虑连接池配置
  4. 批量操作时注意文档大小限制
  5. 合理使用索引提高查询性能

Kivik提供了强大而灵活的方式来与CouchDB/PouchDB交互,支持大多数现代CouchDB功能,包括Mango查询、索引、复制等。它的API设计遵循Golang的惯用模式,使得集成到现有应用中变得简单。

回到顶部