【MongoDB】——golang操作mongodb数据库

10 篇文章 1 订阅

一、前言

     以前一直用着的"gopkg.in/mgo.v2"已经有日子没有人维护了,官方推出了mongo的golang driver,今天有空来看看。

 

二、驱动包获取

"go.mongodb.org/mongo-driver/bson"    //BOSN解析包
"go.mongodb.org/mongo-driver/mongo"    //MongoDB的Go驱动包
"go.mongodb.org/mongo-driver/mongo/options"

三、数据库连接

1. 连接数据库,获取数据库的总大小

package main

import (
	"context"
	"fmt"
	"log"

	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
)

func main() {
	// Rest of the code will go here
	// Set client options 设置连接参数
	clientOptions := options.Client().ApplyURI("mongodb://root:xxxxxxxxxxxxxxxxxxxxxxx@172.20.52.158:41134/?connect=direct;authSource=admin") # connect=direct这个参数设置是副本集我只连接其中一个主节点

	// Connect to MongoDB 连接数据库
	client, err := mongo.Connect(context.TODO(), clientOptions)

	if err != nil {
		log.Fatal(err)
	}

	// Check the connection 测试连接
	err = client.Ping(context.TODO(), nil)

	if err != nil {
		log.Fatal(err)
	}

	fmt.Println("Connected to MongoDB!")

	databases, err := client.ListDatabases(context.TODO(), bson.M{})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(databases.TotalSize / 1024 / 1024 / 1024)
	err = client.Disconnect(context.TODO())

	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("Connection to MongoDB closed.")

}

四、CRUD操作

一旦你已经连接到一个数据库, 是时候添加和操作一些数据了。集合类型有一些函数允许你给数据库发送查询。

1. 插入文档

首先, 创建一些Trainer结构体用来插入到数据库:

ash := Trainer{"Ash", 10, "Pallet Town"}
misty := Trainer{"Misty", 10, "Cerulean City"}
brock := Trainer{"Brock", 15, "Pewter City"}

要插入一个单独的文档, 使用 collection.InsertOne()函数:

insertResult, err := collection.InsertOne(context.TODO(), ash)
if err != nil {
    log.Fatal(err)
}

fmt.Println("Inserted a single document: ", insertResult.InsertedID)

要同时插入多个文档, collection.InsertMany() 函数会采用一个slice对象:

trainers := []interface{}{misty, brock}

insertManyResult, err := collection.InsertMany(context.TODO(), trainers)
if err != nil {
    log.Fatal(err)
}

fmt.Println("Inserted multiple documents: ", insertManyResult.InsertedIDs)

2.更新文档

collection.UpdateOne()函数允许你更新单一的文档, 它需要一个filter文档来匹配数据库里面的文档, 并且需要一个update文档来描述更新的操作。你可以用bson.D类型来构建这些文档:

filter := bson.D{{"name", "Ash"}}

update := bson.D{
    {"$inc", bson.D{
        {"age", 1},
    }},
}

这段代码会匹配name是“Ash”的文档, 并且将Ash的age增加1 —生日快乐, Ash!

updateResult, err := collection.UpdateOne(context.TODO(), filter, update)
if err != nil {
    log.Fatal(err)
}

fmt.Printf("Matched %v documents and updated %v documents.\n", updateResult.MatchedCount, updateResult.ModifiedCount)updateResult, err := collection.UpdateOne(context.TODO(), filter, update)
if err != nil {
    log.Fatal(err)
}

fmt.Printf("Matched %v documents and updated %v documents.\n", updateResult.MatchedCount, updateResult.ModifiedCount)

3. 查找文档

要查询一个文档, 你需要一个filter文档, 以及一个指针在它里边保存结果的解码。要查询单个的文档, 使用collection.FindOne()函数。这个函数返回单个的结果,被解码成为一个值。你可以使用和上面使用过的update查询一样的filter变量来匹配一个name是Ash的文档。

// create a value into which the result can be decoded
var result Trainer

err = collection.FindOne(context.TODO(), filter).Decode(&result)
if err != nil {
    log.Fatal(err)
}

fmt.Printf("Found a single document: %+v\n", result)

要查询多个文档, 使用collection.Find(),这个函数返回一个游标。一个游标提供一个文档流, 通过它你可以遍历和解码每一个文档。一旦一个游标被消耗掉, 你应该关闭游标。这里你也可以使用options包来设定一些操作选项, 特别的, 你可以设定一个返回文档数量的限制, 比如2个。

// Pass these options to the Find method
findOptions := options.Find()
findOptions.SetLimit(2)

// Here's an array in which you can store the decoded documents
var results []*Trainer

// Passing bson.D{{}} as the filter matches all documents in the collection
cur, err := collection.Find(context.TODO(), bson.D{{}}, findOptions)
if err != nil {
    log.Fatal(err)
}

// Finding multiple documents returns a cursor
// Iterating through the cursor allows us to decode documents one at a time
for cur.Next(context.TODO()) {

    // create a value into which the single document can be decoded
    var elem Trainer
    err := cur.Decode(&elem)
    if err != nil {
        log.Fatal(err)
    }

    results = append(results, &elem)
}

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

// Close the cursor once finished
cur.Close(context.TODO())

fmt.Printf("Found multiple documents (array of pointers): %+v\n", results)

4.删除文档

最后, 你可以使用collection.DeleteOne() 或者 collection.DeleteMany()来删除文档。这里, 你传递bson.D{{}}作为filter参数, 这会匹配集合内所有的文档。 你也可以使用collection.Drop()来删除整个集合。

deleteResult, err := collection.DeleteMany(context.TODO(), bson.D{{}})
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Deleted %v documents in the trainers collection\n", deleteResult.DeletedCount)

 

五、参考文章

Mongo-Driver驱动包官方文档
BSON包官方文档
mongo包官方文档
options包官方文档

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Golang 中使用 MongoDB 的事务,需要使用 MongoDB Go 驱动程序提供的事务 API。下面是一个简单的示例: ```go session, err := client.StartSession() if err != nil { log.Fatal(err) } defer session.EndSession(context.Background()) callback := func(sessCtx mongo.SessionContext) (interface{}, error) { coll1 := client.Database("mydb").Collection("collection1") coll2 := client.Database("mydb").Collection("collection2") err := sessCtx.StartTransaction() if err != nil { return nil, err } // Perform operations on collections inside the transaction _, err = coll1.InsertOne(sessCtx, bson.M{"name": "John"}) if err != nil { sessCtx.AbortTransaction(sessCtx) return nil, err } _, err = coll2.InsertOne(sessCtx, bson.M{"name": "Doe"}) if err != nil { sessCtx.AbortTransaction(sessCtx) return nil, err } err = sessCtx.CommitTransaction(sessCtx) if err != nil { return nil, err } return "success", nil } result, err := session.WithTransaction(context.Background(), callback) if err != nil { log.Fatal(err) } fmt.Println(result) ``` 在此示例中,我们使用 `StartSession()` 方法创建一个 MongoDB 会话对象。然后,我们定义一个回调函数 `callback`,该函数包含了我们想要在事务中执行的操作。在回调函数内部,我们首先使用 `StartTransaction()` 方法开始一个事务。然后,我们执行一些操作(例如,在两个集合中插入文档),并在操作完成后调用 `CommitTransaction()` 方法提交事务。如果事务执行过程中出现任何错误,我们可以调用 `AbortTransaction()` 方法回滚事务。 最后,我们使用 `WithTransaction()` 方法来执行回调函数。如果事务执行成功,`WithTransaction()` 方法将返回回调函数的结果,否则将返回一个错误。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值