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

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"}
}}
}}

过滤查询

go 查询

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<len(scoreArray)-1; i++{
filter := bson.M{
"score": bson.M{
"$gt": scoreArray[i],
"$lt": scoreArray[i+1],
},
}
count, err := collection.CountDocuments(context.TODO(), filter)
if err != nil {
log.Printf("get metric error %s", err)
}
if count > 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]

bucket命令

以上的命令其实是用来替换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)

聚合查询

mongo命令使用

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

  1. unwind:将数组中的每一个值拆分为单独的文档
  2. project:提取文档中元素或重命名
  3. match:匹配文档中元素
  4. 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语言执行

go 聚合查询

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:<nil> count:5]

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

go对mongodb的聚合查询的更多相关文章

  1. 使用morphia实现对mongodb的聚合查询

    morphia是谷歌的一个针对mongodb的数据化持久框架: 关于mongodb的介绍不在这里展示,直接进入主题:采用morphia实现对mongodb的聚合查询 这里获取所有学生的分数总和 spr ...

  2. mongodb 高级聚合查询

    mongodb高级聚合查询   在工作中会经常遇到一些mongodb的聚合操作,特此总结下.mongo存储的可以是复杂类型,比如数组.对象等mysql不善于处理的文档型结构,并且聚合的操作也比mysq ...

  3. mongodb高级聚合查询

    在工作中会经常遇到一些mongodb的聚合操作,特此总结下.mongo存储的可以是复杂类型,比如数组.对象等mysql不善于处理的文档型结构,并且聚合的操作也比mysql复杂很多. 注:本文基于 mo ...

  4. mongodb高级聚合查询(转)

    在工作中会经常遇到一些mongodb的聚合操作,特此总结下.mongo存储的可以是复杂类型,比如数组.对象等mysql不善于处理的文档型结构,并且聚合的操作也比mysql复杂很多. 注:本文基于 mo ...

  5. MongoDB的使用学习之(七)MongoDB的聚合查询(两种方式)附项目源码

    先来张在路上…… 铛铛铛……项目源码下载地址:http://files.cnblogs.com/ontheroad_lee/MongoDBDemo.rar 此项目是用Maven创建的,没有使用Mave ...

  6. 【Mongodb】聚合查询 && 固定集合

    概述 数据存储是为了可查询,统计.若数据只需存储,不需要查询,这种数据也没有多大价值 本篇介绍Mongodb 聚合查询(Aggregation) 固定集合(Capped Collections) 准备 ...

  7. MongoDB——》聚合查询(project、match、limit、skip、unwind、group、sort)

    https://blog.csdn.net/weixin_43453386/article/details/85065043#1_testweightname_id_35 https://blog.c ...

  8. mongodb的高级查询

    db的帮助文档 输入:db.help(); db.AddUser(username,password[, readOnly=false])  添加用户 db.auth(usrename,passwor ...

  9. python操作mongodb之二聚合查询

    #聚合查询 from pymongo import MongoClient db = MongoClient('mongodb://10.0.0.9:27017/').aggregation_exam ...

  10. mongodb聚合查询-aggregate

    Mongodb-aggregate 在工作中经常遇到一些mongodb的聚合操作,和mysql对比起来,mongo存储的可以是复杂的类型,比如数组,字典等mysql不善于处理的文档型结构,但是mong ...

随机推荐

  1. Qt源码解析——元对象系统热身

    关键词:Qt 源码 QObject QMetaObject 元对象系统 属性 事件 信号 槽 概述 原系列文章地址 官方文档第二章内容就是元对象系统,它在介绍里描述到: Qt的元对象系统提供了信号和槽 ...

  2. 【纯手工打造】时间戳转换工具(python)

    1.背景 最近发现一个事情,如果日志中的时间戳,需要我们转换成时间,增加可读性.或者将时间转换成时间戳,来配置时间.相信大多人和我一样,都是打开网页,搜索在线时间戳转换工具,然后复制粘贴进去.个人认为 ...

  3. 使用vLLM和ChatGLM3-6b批量推理

    当数据量大的时候,比如百万级别,使用 ChatGLM3-6b 推理的速度是很慢的.发现使用 vLLM 和 ChatGLM3-6b 批量推理极大的提高了推理效率.本文主要通过一个简单的例子进行实践. 1 ...

  4. vulntarget-a-wp

    vulntarget-a 信息收集 存活扫描,目标开放了445还是win7,考虑一手永恒之蓝 arp-scan -l nmap -A -sT -sV 192.168.130.4 永恒之蓝 用nmap的 ...

  5. 使用Bot Framework建立你的第一个聊天机器人

    今天微软给我推送了一个邮件,大概是微软近期开发了很多人工智能相关的API,无意中看到了Bot Framework,就点进去看了看似乎还蛮有意思的.于是准备搭建一个环境试试. 第一步需要下载Bot Ap ...

  6. osgEarth使用笔记2——推荐两个底图数据

    目录 1. 概述 2. 详论 2.1. Blue Marble 2.2. Bright Earth eAtlas Basemap 3. 分享 1. 概述 可以通过osgEarth自带的world.ti ...

  7. 为什么浏览器会提示网站“不安全”?一文读懂https协议与SSL证书

    [摘要] 为什么浏览器会提示网站"不安全"?从浏览器的"不安全"提示来详细了解https与SSL证书.我们打开很多http网站时候,会看到浏览器提示" ...

  8. Kubernetes的拐点助推器:左手开源,右手边缘计算

    摘要:KubeEdge 是首个基于 Kubernetes 扩展的,提供云边协同能力的开放式智能边缘计算平台,也是 CNCF 在智能边缘领域的首个正式项目.依托 Kubernetes 强大的容器编排和调 ...

  9. 华为云GaussDB践行数字化,护航证券保险高质量发展

    摘要:华为云数据库解决方案架构师章哲在由先进数通与华为联合开展的"7+1"系列银行业数字化转型实践交流活动上围绕华为云GaussDB多年来的技术探索和应用实践进行了分享. 近日,由 ...

  10. 案例集锦|科技赋能,华为云GaussDB助千行百业数字化转型

    当下,全社会驶入数字化转型快车道,以科技赋能.智慧转型为主旨的数字生态推动着千行百业的变革.数据库作为企业核心数据底座,华为云提供了安全可靠的云原生底座和一站式上云解决方案.其中华为云GaussDB覆 ...