go对mongodb的聚合查询

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肯定离不开聚合查询这种威力强大的操作。下面实现一个提取数组中元素,重命名,匹配区间,统计总数这样一个操作,使用到的命令包括:
- 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语言执行
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的聚合查询的更多相关文章
- 使用morphia实现对mongodb的聚合查询
morphia是谷歌的一个针对mongodb的数据化持久框架: 关于mongodb的介绍不在这里展示,直接进入主题:采用morphia实现对mongodb的聚合查询 这里获取所有学生的分数总和 spr ...
- mongodb 高级聚合查询
mongodb高级聚合查询 在工作中会经常遇到一些mongodb的聚合操作,特此总结下.mongo存储的可以是复杂类型,比如数组.对象等mysql不善于处理的文档型结构,并且聚合的操作也比mysq ...
- mongodb高级聚合查询
在工作中会经常遇到一些mongodb的聚合操作,特此总结下.mongo存储的可以是复杂类型,比如数组.对象等mysql不善于处理的文档型结构,并且聚合的操作也比mysql复杂很多. 注:本文基于 mo ...
- mongodb高级聚合查询(转)
在工作中会经常遇到一些mongodb的聚合操作,特此总结下.mongo存储的可以是复杂类型,比如数组.对象等mysql不善于处理的文档型结构,并且聚合的操作也比mysql复杂很多. 注:本文基于 mo ...
- MongoDB的使用学习之(七)MongoDB的聚合查询(两种方式)附项目源码
先来张在路上…… 铛铛铛……项目源码下载地址:http://files.cnblogs.com/ontheroad_lee/MongoDBDemo.rar 此项目是用Maven创建的,没有使用Mave ...
- 【Mongodb】聚合查询 && 固定集合
概述 数据存储是为了可查询,统计.若数据只需存储,不需要查询,这种数据也没有多大价值 本篇介绍Mongodb 聚合查询(Aggregation) 固定集合(Capped Collections) 准备 ...
- MongoDB——》聚合查询(project、match、limit、skip、unwind、group、sort)
https://blog.csdn.net/weixin_43453386/article/details/85065043#1_testweightname_id_35 https://blog.c ...
- mongodb的高级查询
db的帮助文档 输入:db.help(); db.AddUser(username,password[, readOnly=false]) 添加用户 db.auth(usrename,passwor ...
- python操作mongodb之二聚合查询
#聚合查询 from pymongo import MongoClient db = MongoClient('mongodb://10.0.0.9:27017/').aggregation_exam ...
- mongodb聚合查询-aggregate
Mongodb-aggregate 在工作中经常遇到一些mongodb的聚合操作,和mysql对比起来,mongo存储的可以是复杂的类型,比如数组,字典等mysql不善于处理的文档型结构,但是mong ...
随机推荐
- Qt源码解析——元对象系统热身
关键词:Qt 源码 QObject QMetaObject 元对象系统 属性 事件 信号 槽 概述 原系列文章地址 官方文档第二章内容就是元对象系统,它在介绍里描述到: Qt的元对象系统提供了信号和槽 ...
- 【纯手工打造】时间戳转换工具(python)
1.背景 最近发现一个事情,如果日志中的时间戳,需要我们转换成时间,增加可读性.或者将时间转换成时间戳,来配置时间.相信大多人和我一样,都是打开网页,搜索在线时间戳转换工具,然后复制粘贴进去.个人认为 ...
- 使用vLLM和ChatGLM3-6b批量推理
当数据量大的时候,比如百万级别,使用 ChatGLM3-6b 推理的速度是很慢的.发现使用 vLLM 和 ChatGLM3-6b 批量推理极大的提高了推理效率.本文主要通过一个简单的例子进行实践. 1 ...
- vulntarget-a-wp
vulntarget-a 信息收集 存活扫描,目标开放了445还是win7,考虑一手永恒之蓝 arp-scan -l nmap -A -sT -sV 192.168.130.4 永恒之蓝 用nmap的 ...
- 使用Bot Framework建立你的第一个聊天机器人
今天微软给我推送了一个邮件,大概是微软近期开发了很多人工智能相关的API,无意中看到了Bot Framework,就点进去看了看似乎还蛮有意思的.于是准备搭建一个环境试试. 第一步需要下载Bot Ap ...
- osgEarth使用笔记2——推荐两个底图数据
目录 1. 概述 2. 详论 2.1. Blue Marble 2.2. Bright Earth eAtlas Basemap 3. 分享 1. 概述 可以通过osgEarth自带的world.ti ...
- 为什么浏览器会提示网站“不安全”?一文读懂https协议与SSL证书
[摘要] 为什么浏览器会提示网站"不安全"?从浏览器的"不安全"提示来详细了解https与SSL证书.我们打开很多http网站时候,会看到浏览器提示" ...
- Kubernetes的拐点助推器:左手开源,右手边缘计算
摘要:KubeEdge 是首个基于 Kubernetes 扩展的,提供云边协同能力的开放式智能边缘计算平台,也是 CNCF 在智能边缘领域的首个正式项目.依托 Kubernetes 强大的容器编排和调 ...
- 华为云GaussDB践行数字化,护航证券保险高质量发展
摘要:华为云数据库解决方案架构师章哲在由先进数通与华为联合开展的"7+1"系列银行业数字化转型实践交流活动上围绕华为云GaussDB多年来的技术探索和应用实践进行了分享. 近日,由 ...
- 案例集锦|科技赋能,华为云GaussDB助千行百业数字化转型
当下,全社会驶入数字化转型快车道,以科技赋能.智慧转型为主旨的数字生态推动着千行百业的变革.数据库作为企业核心数据底座,华为云提供了安全可靠的云原生底座和一站式上云解决方案.其中华为云GaussDB覆 ...