Golang对mongodb进行聚合查询详解

Yasmin ·
更新时间:2024-11-13
· 1385 次阅读

目录

1.BSON介绍

2.过滤查询

2.1go查询

2.2bucket命令

3.聚合查询

3.1mongo命令使用

3.2go 聚合查询

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<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]

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

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

以上就是Golang对mongodb进行聚合查询详解的详细内容,更多关于Golang mongodb聚合查询的资料请关注软件开发网其它相关文章!



MongoDB golang

需要 登录 后方可回复, 如果你还没有账号请 注册新账号