Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >MongoDB Golang 示例代码

MongoDB Golang 示例代码

原创
作者头像
IT工作者
发布于 2022-07-20 01:57:45
发布于 2022-07-20 01:57:45
5440
举报
文章被收录于专栏:程序技术知识程序技术知识

包含 增删改查,索引设置,事务,max,cout等的使用 和 压力测试

主要是要适应习惯 bson.M/A/D的使用

其中事务需要有 replica set集群支持

完整代码如下:

代码语言:go
AI代码解释
复制
package main
 
import (
    "context"
    "flag"
    "fmt"
    "go.mongodb.org/mongo-driver/bson"
    "log"
    "math/rand"
    "sync"
    "time"
 
    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
    //"go.mongodb.org/mongo-driver/bson/primitive"
)
 
type testStruct struct {
    ID uint64
    Name string
}
 
var ID uint64
var l sync.Mutex
func genID() uint64 {
 
    l.Lock()
    defer  l.Unlock()
    ID += 1
    return ID
}
 
func main() {
 
    var rcot int    // insert 协程数
    var frcot int    // find 协程数
 
    flag.IntVar(&rcot, "c", 1, "insert go routine count")
    flag.IntVar(&frcot, "f", 1, "find go routine count")
    flag.Parse()
 
    clientOptions := options.Client().ApplyURI("mongodb://localhost:27017")
    client, err := mongo.Connect(context.TODO(),clientOptions)
    if err != nil {
        return
    }
 
 
    db := client.Database("test")
    col := db.Collection("colA")
 
    // 初始化最大ID, 使用两种方式获取最大值
    //initID()    // 使用聚合,效率较低
    initIDEx(col)    // 有索引,使用sort效率较高
 
    // 压力测试插入
    testInsert( col, rcot)
 
    // 各种情况查询
    find2(col)
 
    // 更新
    update(col)
 
    // 测试删除
    count(col)
    delete(col)
    count(col)
 
    // 测试事务, 需要开启replica set 集群
    transaction(client)
 
    // 设置索引
    testIndex(col)
 
    //  压力测试 查询
    find(col, frcot)
 
}
 
// 更新
func update(col *mongo.Collection) {
    rand.Seed(int64(time.Now().UnixNano()))
    id := rand.Uint64()%ID
    filter := bson.D{{"id", id}}
    update := bson.D{{"$set", bson.D{{"name", "xxxxxxx"}}}}
 
    result,err := col.UpdateOne(context.TODO(), filter, update )
    if err != nil {
        log.Println(err)
        return
    }
    fmt.Println("update count:", result.ModifiedCount)
 
}
 
// 删除
func delete(col *mongo.Collection) {
    rand.Seed(int64(time.Now().Second()) )
    id := rand.Uint64()%ID
    filter := bson.D{{"id", id}}
    res, err := col.DeleteOne(context.TODO(), filter)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println( "delete count", res.DeletedCount)
}
 
// Count 数量统计
func count(col *mongo.Collection) {
    cot,_ := col.CountDocuments(context.TODO(), bson.D{})
    fmt.Println("count:", cot)
}
 
// 事务
func transaction(client *mongo.Client) {
 
    fmt.Println("start test transaction")
 
    db := client.Database("test")
    col := db.Collection("colA")
 
    count(col)
 
    ctx := context.Background()
 
    err := client.UseSession(ctx, func(sessioinContext mongo.SessionContext) error {
 
        if err := sessioinContext.StartTransaction(); err !=nil {
            return er
        }
 
        res, err := col.InsertOne(sessioinContext, bson.M{"id":genID(), "name":GenRandStr(12)})
        if err != nil {
            fmt.Println("insert err in transaction:", err)
            return er
        }
        fmt.Println("insert result:", res.InsertedID)
 
        err = sessioinContext.CommitTransaction(sessioinContext)
        if err != nil {
            fmt.Println("commit transaction err:", err)
        }
        return nil
    })
    if err != nil {
        fmt.Println("trans err:", err)
        return
    }
 
    count(col)
    fmt.Println("end test transaction")
 
}
 
 
// 查询
func find2(col *mongo.Collection){
 
    // 查询ID小于等于3的项
    fo := options.FindOptions{}
    fo.SetLimit(2)    // 不设置limit,会查处3个值
    //fo.SetSort(bson.D{{"id", -1}})
    cur, err:= col.Find(context.TODO(), bson.D{{"id",bson.D{{"$lte",3}}}}, &fo)
    if err != nil {
        panic(err)
    }
    defer cur.Close(context.TODO())
 
    // 批量decode
    var a []testStruct
    cur.All(context.TODO(), &a)
    fmt.Println("find all result:", a)
 
    // 逐个迭代decode (这里并不会进去,除非注释上面的All(),具体原因看All接口的注释说明)
    for cur.Next(context.TODO()){
        temp := testStruct{}
        cur.Decode(&temp)
        println(temp.ID, temp.Name)
    }
 
    // 使用findOne 进行多条件查询
    res := col.FindOne(context.TODO(), bson.D{{"id", a[0].ID},{"name", a[0].Name}})
 
    t := testStruct{}
    res.Decode(&t)
    fmt.Println( "multiple conditions query:", t.ID, t.Name)
}
 
// 生成随机字符串
func GenRandStr(len int) string {
 
    bs := make([]byte, 0, len)
    for i:=0; i<len;i++{
        r := rand.Int()%26
        bs = append(bs, 'a'+byte(r))
    }
    return string(bs)
}
 
 
// max 聚合
func initID(col *mongo.Collection) {
    pip := mongo.Pipeline{bson.D{
        {"$group", bson.D{
            {"_id", ""},
            {"maxid", bson.D{{"$max", "$id"}}},
        },
        }},
    }
    cur, err := col.Aggregate(context.TODO(), pip)
    if err != nil {
        log.Println(err)
        return
    }
    defer cur.Close(context.TODO())
 
    var results []bson.M
    cur.All(context.TODO(), &results)
    for _, result := range results {
        fmt.Println(result)
        if v, ok := result["maxid"]; ok {
            println("max id is ", v.(int64))
            ID = uint64(v.(int64))
        }
    }
}
 
// max findOne sort
func initIDEx(col *mongo.Collection) {
    findOp := options.FindOne()
    findOp.SetSort(bson.D{{"id", -1}})
    rst := col.FindOne(context.TODO(), bson.D{}, findOp)
 
    var a testStruct
    if err := rst.Decode(&a); err == nil {
        ID = a.ID
        println("max id:", ID)
    }
 
}
 
 
// 查询
func testFind(col *mongo.Collection, wg *sync.WaitGroup){
    t0:=time.Now()
    for k:=0;k<10000;k++{
        id := rand.Uint64()%ID
        cur, err:= col.Find(context.TODO(), bson.D{{"id",id}})
        if err != nil {
            panic(err)
        }
 
        for cur.Next(context.TODO()){
            a := testStruct{}
            cur.Decode(&a)
            if a.ID != id {
                println(a.ID, id, ID)
 
            }
        }
 
        cur.Close(context.TODO())
    }
    fmt.Println("find use time:", time.Since(t0))
    wg.Done()
}
 
// 查询压力测试
func find(col *mongo.Collection, cot int) {
    wg := sync.WaitGroup{}
    wg.Add(cot)
    t0:=time.Now()
    for k:=0;k<cot;k++{
        go testFind(col, &wg)
    }
    wg.Wait()
    fmt.Println(cot, "go routine find total use time ", time.Since(t0))
 
}
 
// 索引
func testIndex(col *mongo.Collection) {
    indexName, err := col.Indexes().CreateOne(
        context.Background(),
        mongo.IndexModel{
            Keys: bson.M{"id": 1},
            Options: options.Index().SetUnique(true),
        },
    )
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("index name:", indexName)
 
}
 
func testInsert( col *mongo.Collection, rcot int) {
    t0:=time.Now()
    wg := sync.WaitGroup{}
    for k:=0;k<rcot;k++{
        wg.Add(1)
        go insert(col, &wg)
    }
    wg.Wait()
    fmt.Println(rcot, "go routines insert total use time:", time.Since(t0))
}
 
// 插入
func insert(col *mongo.Collection, wg *sync.WaitGroup) {
    defer wg.Done()
 
    t0:=time.Now()
    for i:=0;i<10000;i++{
        //tdata := testStruct{
        //    ID: genID(),
        //    Name: GenRandStr(12),
        //}
        //_,err := col.InsertOne(context.TODO(), &tdata)
 
        // 上面的方式也可以
        _, err := col.InsertOne(context.TODO(), bson.M{"id":genID(), "name":GenRandStr(12)})
        if err != nil {
            fmt.Println(err)
            return
        }
    }
 
    //fmt.Println("Last insert id:", res.InsertedID)
    fmt.Println("insert 10000 data use time:", time.Since(t0))
}

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Go 操作mongodb
添加mongodb驱动程序 用于go get将 Go 驱动程序添加为依赖项。 go get go.mongodb.org/mongo-driver/mongo 使用方法 创建main.go 文件 package main import ( "context" "fmt" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mon
孤烟
2022/10/08
6330
使用Golang驱动操作MongoDB
mongo.Connect()接受Context和options.ClientOptions对象,该对象用于设置连接字符串和其他驱动程序设置。 通过context.TODO()表示不确定现在使用哪种上下文,但是会在将来添加一个 使用Ping方法来检测是否已正常连接MongoDB
没有故事的陈师傅
2020/11/03
4.9K0
Go操作MongoDB
mongoDB是目前比较流行的一个基于分布式文件存储的数据库,它是一个介于关系数据库和非关系数据库(NoSQL)之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。
iginkgo18
2021/09/13
2.4K0
MongoDB Go Driver使用帮助文档
正式的MongoDB Go Driver近来变成1.0的GA版本。它现在被认为是一个完整的特性, 并且准备好在正式产品中使用。这篇使用说明书将帮助你开始使用 MongoDB Go Driver。你将会创建一个简单的程序并且学到如何:
MongoDB中文社区
2019/08/20
4K0
MongoDB Go Driver使用帮助文档
MongoDB max 获取最大值 (Golang)
某个集合, 要获取某个字段的最大值,有两种办法,一个是用sort, 另一个是用聚合(Aggregate),下面是代码演示:
IT工作者
2022/07/19
1.4K0
go-mongox:简单高效,让文档操作和 bson 数据构造更流畅
在 Go 语言中使用 MongoDB 官方框架进行集合操作时,深深感到构建 bson 数据是一件非常繁琐的工作。字段、逗号,括号等符号的排列,让我感觉仿佛是在进行一场拼图游戏。因此我在想,有没有一个能让我丝滑,高效操作 MongoDB 的第三方框架呢,遗憾的是,并没有找到符合我预期的框架,索性我就自己动手开发了一个,这就是 go-mongox 框架的由来。
陈明勇
2023/11/14
4860
go-mongox:简单高效,让文档操作和 bson 数据构造更流畅
一文搞懂MongoDB比较查询运算符
闫同学
2023/12/07
3636
Golang 与mongodb的交互。嵌套struct
mongodb这类nosql数据库,还是先定义结构比较好啊。存取方便。蛋疼的是golang定义个嵌套的struct好费劲啊。。 primitive.NewObjectID() 可以生成一个mongodb的_id,找了半天这个函数。网上都是 mgo的函数。好像好久不更新了。mongo-driver是mongodb的官方驱动?所以不用第三方的了吧。
xiny120
2019/07/17
4.8K0
Go学习——使用MongoDB
MongoDB是一个高性能,开源,无模式的文档型数据库,是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。他支持的数据结构非常松散,采用的是类似json的bjson格式来存储数据,因此可以存储比较复杂的数据类型。Mongo最大的特点是他支持的查询语言非常强大,其语法有点类似于面向 对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。
传说之下的花儿
2023/04/16
6260
Go中级之手把手教你开发一个简易的个人博客网站(一)项目基本架构和数据库链接
此文是个人学习归纳的记录,腾讯云独家发布,未经允许,严禁转载,如有不对, 还望斧正, 感谢!
言志志
2023/12/22
2.4K1
Go中级之手把手教你开发一个简易的个人博客网站(一)项目基本架构和数据库链接
Go高级之Gin框架和Mongodb数据库的联动
这次总结,主要还是我之前打算用Gin写一个自己的个人博客网站来练手,我没有选择常用的MySQL,而是打算使用MongoDB作为个人博客网站数据库,有以下几点原因:
言志志
2023/11/07
1.3K0
Go高级之Gin框架和Mongodb数据库的联动
Mongo之ChangeStream详解
Change Stream可以直译为"变更流",也就是说会将数据库中的所有变更以流式的方式呈现出来。用户可以很方便地对数据库建立一个监听(订阅)进程,一旦数据库发生变更,使用change stream的客户端都可以收到相应的通知。使用场景可以包括但不限于以下几种:
tunsuy
2023/08/19
5050
Mongo之ChangeStream详解
持续搞【附近】---长连接坐标流和“地理围栏”(五)
我们经过【附近】系列的二、三、四篇章后,已经基本了解了市面上用于解决LBS问题的几种常见方案和做法,当然除了PostGre外... ...那个有兴趣的哥们可以考虑补一篇PostGre版本直接投稿。实际上前面的思路是很简单的,算是循序渐进类型的,从MySQL到MongoDB再到ES,大概就是从GeoHASH到Google S2再到R树们。我没有在文章里显式地说这些但是背后就是这些,往深处地挖掘全靠诸位自己了~
老李秀
2019/11/13
9980
持续搞【附近】---长连接坐标流和“地理围栏”(五)
Go高级之关于MongoDB中的BSON
BSON(Binary JSON)是一种二进制表示的JSON格式,用于在MongoDB中存储和传输数据。它是MongoDB的原生数据格式,并且被广泛用于MongoDB的各种操作和功能。
言志志
2023/11/08
1.1K1
Go高级之关于MongoDB中的BSON
Go 语言 mongox 库:简化操作、安全、高效、可扩展、BSON 构建
在 Go 语言里使用 MongoDB 官方提供的 mongo-go-driver 库进行集合操作时,你是否感到结构体与 MongoDB 集合之间的映射,以及构建 BSON 数据这些操作极其繁琐?特别是在构建 BSON 数据时,各种字段、逗号和括号的排列组合是否让你觉得仿佛在进行一场复杂的拼图游戏?
陈明勇
2024/06/08
2564
Go 语言 mongox 库:简化操作、安全、高效、可扩展、BSON 构建
MONGDB安装与使用
网址:https://www.mongodb.com/try/download/community
阿兵云原生
2023/02/16
5100
Go Mongox:轻松实现 MongoDB 时间字段自动填充
 时,例如执行插入或更新操作,我们需要手动设置这些时间字段的值。然而,每次手动赋值不仅繁琐,还容易导致代码重复。那么,是否可以在程序层面实现自动填充呢?
陈明勇
2025/02/09
38715
MONGDB 安装与使用
是非关系数据库当中功能最丰富,它支持的数据结构非常松散,是类似 JSON 的 BSON 格式的
阿兵云原生
2023/02/16
5650
golang学习之mgo操作mongodb
mgo是mongodb的golang驱动,测试代码: // mgotest project main.go package main import ( "fmt" "time"
用户1141560
2017/12/26
2.1K0
Go Mongox 开源库设计分享:简化 MongoDB 开发的最佳实践
在使用 Go 语言操作 MongoDB 时,Go 开发者的首选库通常是由 MongoDB 官方团队推出的 mongo-go-driver。这个库是专为 Go 语言开发者打造的,支持 MongoDB 的主要功能,并与最新版本的 MongoDB 兼容。通过 mongo-go-driver,Go 开发者可以便捷地连接数据库,并且能对集合进行查询、插入、更新、删除的操作。
陈明勇
2024/11/28
4476
Go Mongox 开源库设计分享:简化 MongoDB 开发的最佳实践
相关推荐
Go 操作mongodb
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档