当前位置:首页 > 文章列表 > Golang > Go教程 > Golang对mongodb进行聚合查询详解

Golang对mongodb进行聚合查询详解

来源:脚本之家 2023-02-25 09:25:19 0浏览 收藏

积累知识,胜过积蓄金银!毕竟在##column_title##开发的过程中,会遇到各种各样的问题,往往都是一些细节知识点还没有掌握好而导致的,因此基础知识点的积累是很重要的。下面本文《Golang对mongodb进行聚合查询详解》,就带大家讲解一下mongodb、查询、聚合知识点,若是你对本文感兴趣,或者是想搞懂其中某个知识点,就请你继续往下看吧~

mongodb的环境搭建参考前面一篇通过mongo-driver使用说明 GO 包管理机制

1.BSON介绍

在Go中使用BSON对象构建操作命令

在我们发送查询给数据库之前, 很重要的一点是,理解Go Driver是如何和BSON对象协同工作的。

JSON文档在MongoDB里面以二进制形式存储, 被称作BSON(二进制编码的JSON)。不像其他的数据库保存JSON数据为简单的字符串和数字, BSON扩展了JSON的保存形式, 包括额外的类型, 比如int, long, date, floating point以及decimal128。这使得它让应用程序更容易来可靠地处理、排序和比较数据。

Go Driver有两个系列的类型表示BSON数据:D系列类型和Raw系列类型。

D系列的类型使用原生的Go类型简单地构建BSON对象。这可以非常有用的来创建传递给MongoDB的命令。 D系列包含4种类型:

  • – D:一个BSON文档。这个类型应该被用在顺序很重要的场景, 比如MongoDB命令。
  • – M: 一个无需map。 它和D是一样的, 除了它不保留顺序。
  • – A: 一个BSON数组。
  • – E: 在D里面的一个单一的子项。

这里有一个使用D类型构建的过滤文档的例子, 它可能被用在查询name字段匹配“Alice”或者“Bob”的文档:

bson.D{{
    "name", 
    bson.D{{
        "$in", 
        bson.A{"Alice", "Bob"}
    }}
}}

2.过滤查询

2.1go查询

package main

import (
    "context"
    "fmt"
    "log"

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

type Student struct {
    Name string
    Score int 
}

func main() {
    // 设置客户端连接配置
    clientOptions := options.Client().ApplyURI("mongodb://admin:123456@localhost:27017")

    // 连接到MongoDB
    client, err := mongo.Connect(context.TODO(), clientOptions)
    if err != nil {
        log.Fatal(err)
    }

    // 检查连接
    err = client.Ping(context.TODO(), nil)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("Connected to MongoDB!")


    collection := client.Database("demo").Collection("student")
    

    s1 := Student{"小红", 66}
    s2 := Student{"小兰", 70}
    s3 := Student{"小黄", 86}
    s4 := Student{"小张", 92}


    students := []interface{}{s1, s2, s3, s4}
    res, err := collection.InsertMany(context.TODO(), students)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("插入数据完成", res.InsertedIDs)

    
    aggreData := []map[string]interface{}{}

    scoreArray := [5]int{60, 70, 80, 90, 100}

  
    for i := 0; i 0 {
            temp := map[string]interface{}{}
            temp["count"] = count
            aggreData = append(aggreData, temp)
        }
    }
    
    fmt.Println("get finish!")
    for _, value := range aggreData {
        fmt.Println(value)
    }
}
admin> use demo
switched to db demo
demo> show tables
student
demo> db.student.find()
[
  { _id: ObjectId("63e25fa9c6fe361e9f5e7e6e"), name: '小红', score: 66 },
  { _id: ObjectId("63e25fa9c6fe361e9f5e7e6f"), name: '小兰', score: 70 },
  { _id: ObjectId("63e25fa9c6fe361e9f5e7e70"), name: '小黄', score: 86 },
  { _id: ObjectId("63e25fa9c6fe361e9f5e7e71"), name: '小张', score: 92 }
]

➜  mongo go run hello.go
Connected to MongoDB!
插入数据完成 [ObjectID("63e26329b1f99ae321f895c2") ObjectID("63e26329b1f99ae321f895c3") ObjectID("63e26329b1f99ae321f895c4") ObjectID("63e26329b1f99ae321f895c5")]
get finish!
map[count:1]
map[count:1]
map[count:1]

2.2bucket命令

以上的命令其实是用来替换bucket命令。bucket命令是3.4的新功能,功能是可以对传入的一组查询数据分组查询并统计。如传入查询数据为[0, 10, 20, 30],可以查询出0~10的数据,10~20的数据。

cond := make([]bson.M, 0)
cond = append(cond, bson.M{"$match": bson.M{"user_id": userID}})
cond = append(cond, bson.M{
    "$bucket": bson.D{
        bson.E{Key: "groupBy", Value: "$" + queryField},
        bson.E{Key: "default", Value: "_others_"},
        bson.E{Key: "boundaries", Value: boundries},
        bson.E{Key: "output", Value: bson.D{bson.E{Key: "count", Value: bson.M{"$sum": 1}}}},
    }})
aggreData := s.aggregateMongoQuery(collection, cond)

3.聚合查询

3.1mongo命令使用

使用mongodb肯定离不开聚合查询这种威力强大的操作。下面实现一个提取数组中元素,重命名,匹配区间,统计总数这样一个操作,使用到的命令包括:

  • unwind:将数组中的每一个值拆分为单独的文档
  • project:提取文档中元素或重命名
  • match:匹配文档中元素
  • group:统计文档

插入数据

demo> db.student.insert({"field": "score", "num": [12, 23, 34, 45, 56, 67, 78, 89]})
{
  acknowledged: true,
  insertedIds: { '0': ObjectId("63e3b26b029e307c2c8c46e6") }
}

mongo命令查询

demo> db.student.aggregate([{ $unwind:"$num"}, {$project:{value: "$num"}}, {$match: {value:{$gte: 40, $lt: 90}}}, {$group: {_id: "in_40_90", count: {$sum: 1}}}])
[ { _id: 'in_40_90', count: 5 } ]

程序就是将以上命令翻译成go语言执行

3.2go 聚合查询

package main

import (
    "context"
    "fmt"
    "log"

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

type Student struct {
    Name string
    Score int 
}

func main() {
    // 设置客户端连接配置
    clientOptions := options.Client().ApplyURI("mongodb://admin:123456@localhost:27017")

    // 连接到MongoDB
    client, err := mongo.Connect(context.TODO(), clientOptions)
    if err != nil {
        log.Fatal(err)
    }

    // 检查连接
    err = client.Ping(context.TODO(), nil)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("Connected to MongoDB!")

    collection := client.Database("demo").Collection("student")
    
    
    unwind := bson.D{{"$unwind", "$num"}}

    project := bson.D{{
        "$project", bson.D{{
            "value", "$num",
        }},
    }}

    match := bson.D{{
        "$match", bson.D{{
            "value", bson.D{{"$gte", 40}, {"$lt", 90}},
        }},
    }}

    group := bson.D{{
        "$group", bson.D{
            {"_id", nil},
            {"count", bson.D{{"$sum", 1}}},
        },
    }}
    showInfoCursor, err := collection.Aggregate(context.TODO(), mongo.Pipeline{unwind, project, match, group})

    var showsWithInfo []map[string]interface{}
    if err = showInfoCursor.All(context.TODO(), &showsWithInfo); err != nil {
        log.Printf("collection %s", err)
        panic(err)
    }

    for _, value := range showsWithInfo {
        fmt.Println(value)
    }

}

➜  mongo go run hello.go
Connected to MongoDB!
map[_id: count:5]
 

可以看到结果和mongo命令是一样的

今天关于《Golang对mongodb进行聚合查询详解》的内容介绍就到此结束,如果有什么疑问或者建议,可以在golang学习网公众号下多多回复交流;文中若有不正之处,也希望回复留言以告知!

版本声明
本文转载于:脚本之家 如有侵犯,请联系study_golang@163.com删除
MySQL实现数据更新的示例详解MySQL实现数据更新的示例详解
上一篇
MySQL实现数据更新的示例详解
解读SQL语句中要不要加单引号的问题
下一篇
解读SQL语句中要不要加单引号的问题
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    542次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    508次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    497次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    484次学习
查看更多
AI推荐
  • 笔灵AI生成答辩PPT:高效制作学术与职场PPT的利器
    笔灵AI生成答辩PPT
    探索笔灵AI生成答辩PPT的强大功能,快速制作高质量答辩PPT。精准内容提取、多样模板匹配、数据可视化、配套自述稿生成,让您的学术和职场展示更加专业与高效。
    13次使用
  • 知网AIGC检测服务系统:精准识别学术文本中的AI生成内容
    知网AIGC检测服务系统
    知网AIGC检测服务系统,专注于检测学术文本中的疑似AI生成内容。依托知网海量高质量文献资源,结合先进的“知识增强AIGC检测技术”,系统能够从语言模式和语义逻辑两方面精准识别AI生成内容,适用于学术研究、教育和企业领域,确保文本的真实性和原创性。
    22次使用
  • AIGC检测服务:AIbiye助力确保论文原创性
    AIGC检测-Aibiye
    AIbiye官网推出的AIGC检测服务,专注于检测ChatGPT、Gemini、Claude等AIGC工具生成的文本,帮助用户确保论文的原创性和学术规范。支持txt和doc(x)格式,检测范围为论文正文,提供高准确性和便捷的用户体验。
    30次使用
  • 易笔AI论文平台:快速生成高质量学术论文的利器
    易笔AI论文
    易笔AI论文平台提供自动写作、格式校对、查重检测等功能,支持多种学术领域的论文生成。价格优惠,界面友好,操作简便,适用于学术研究者、学生及论文辅导机构。
    38次使用
  • 笔启AI论文写作平台:多类型论文生成与多语言支持
    笔启AI论文写作平台
    笔启AI论文写作平台提供多类型论文生成服务,支持多语言写作,满足学术研究者、学生和职场人士的需求。平台采用AI 4.0版本,确保论文质量和原创性,并提供查重保障和隐私保护。
    35次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议隐私政策
返回登录
  • 重置密码