前言
在 Go
语言中使用 MongoDB
官方框架进行集合操作时,深深感到构建 bson
数据是一件非常繁琐的工作。字段、逗号,括号等符号的排列,让我感觉仿佛是在进行一场拼图游戏。
因此我在想,有没有一个能让我丝滑,高效操作 MongoDB
的第三方框架呢,遗憾的是,并没有找到符合我预期的框架,索性我就自己动手开发了一个,这就是 go-mongox
框架的由来。
如果你也有类似我的这种感受,相信 go-mongox
框架能给你带来不一样的体验。
go-mongox
go-mongox
基于 泛型 对 MongoDB
官方框架进行了二次封装,它通过使用链式调用的方式,让我们能够丝滑地操作文档。同时,其还提供了多种类型的 bson
构造器,帮助我们高效的构建 bson
数据。
仓库地址:https://github.com/chenmingyong0423/go-mongox
该框架处于初期阶段,希望通过集思广益的方式,邀请各位开发者共同参与,提出宝贵的建议和意见,共同打造一个更强大、更灵活的框架。期待着您的积极参与和宝贵反馈,共同推动go-mongox
不断进步。
功能
- 文档的
crud
操作 - 聚合操作
- 构造
bson
数据 - ······(敬请期待)
安装
1
|
go get github.com /chenmingyong0423/go-mongox @latest |
collection 集合操作
基于泛型的 collection 形态初始化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
package main import ( "context" "github.com/chenmingyong0423/go-mongox" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" "go.mongodb.org/mongo-driver/mongo/readpref" ) type Post struct { Id string `bson: "_id" ` Title string `bson: "title" ` Author string `bson: "author" ` Content string `bson: "content" ` } func main() { // 你需要预先创建一个 *mongo.Collection 对象 mongoCollection := newCollection() // 使用 Post 结构体作为泛型参数创建一个 collection postCollection := mongox.NewCollection[Post](mongoCollection) } // 示例代码,不是最佳的创建方式 func newCollection() *mongo.Collection { client, err := mongo.Connect(context.Background(), options.Client().ApplyURI( "mongodb://localhost:27017" ).SetAuth(options.Credential{ Username: "test" , Password: "test" , AuthSource: "db-test" , })) if err != nil { panic (err) } err = client.Ping(context.Background(), readpref.Primary()) if err != nil { panic (err) } collection := client.Database( "db-test" ).Collection( "test_post" ) return collection } |
通过 mongox.NewCollection
函数,我们可以创建一个基于泛型的 collection
装饰器。
Creator 创造器
Creator
是一个创造器,用于执行插入相关的操作。
插入单个文档
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
// https://github.com/chenmingyong0423/blog/blob/master/tutorial-code/go-mongox/collection/creator/insert_one.go package main import ( "chenmingyong0423/blog/tutorial-code/go-mongox/collection" "context" "fmt" "github.com/chenmingyong0423/go-mongox" "go.mongodb.org/mongo-driver/mongo/options" ) func main() { // 你需要预先创建一个 *mongo.Collection 对象 mongoCollection := collection.NewCollection() // 使用 Post 结构体作为泛型参数创建一个 collection postCollection := mongox.NewCollection[collection.Post](mongoCollection) // 插入一个文档 doc := collection.Post{Id: "1" , Title: "go-mongox" , Author: "陈明勇" , Content: "go-mongox,不一样的体验。" } oneResult, err := postCollection.Creator().InsertOne(context.Background(), doc) if err != nil { panic (err) } fmt. Println (oneResult.InsertedID.( string ) == "1" ) // true // 携带 option 参数 oneResult, err = postCollection.Creator().OneOptions(options.InsertOne().SetComment( "test" )).InsertOne(context.Background(), collection.Post{Id: "2" , Title: "go 语言 go-mongox 库的使用教程" , Author: "陈明勇" , Content: "go-mongox 旨在提供更方便和高效的MongoDB数据操作体验。" }) if err != nil { panic (err) } fmt. Println (oneResult.InsertedID.( string ) == "2" ) // true } |
基于 postCollection
实例,我们可以通过 Creator()
方法创建一个创造器,然后进行插入操作。
InsertOne
方法与官方的 API
同名,作用是插入一条数据。如果我们想要设置 options
参数,应使用 OneOptions
方法。
可以看到,无论是设置 options
参数还是执行插入操作,都在一条链路上完成,即实现了链式操作。
插入多个文档
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
// https://github.com/chenmingyong0423/blog/blob/master/tutorial-code/go-mongox/collection/creator/insert_many.go package main import ( "chenmingyong0423/blog/tutorial-code/go-mongox/collection" "context" "fmt" "github.com/chenmingyong0423/go-mongox" "go.mongodb.org/mongo-driver/mongo/options" ) func main() { // 你需要预先创建一个 *mongo.Collection 对象 mongoCollection := collection.NewCollection() // 使用 Post 结构体作为泛型参数创建一个 collection postCollection := mongox.NewCollection[collection.Post](mongoCollection) docs := []collection.Post{ {Id: "1" , Title: "go" , Author: "陈明勇" , Content: "..." }, {Id: "2" , Title: "mongo" , Author: "陈明勇" , Content: "..." }, } manyResult, err := postCollection.Creator().InsertMany(context.Background(), docs) if err != nil { panic (err) } fmt. Println ( len (manyResult.InsertedIDs) == 2 ) // true // 携带 option 参数 manyResult, err = postCollection.Creator().ManyOptions(options.InsertMany().SetComment( "test" )).InsertMany(context.Background(), []collection.Post{ {Id: "3" , Title: "go-mongox" , Author: "陈明勇" , Content: "..." }, {Id: "4" , Title: "builder" , Author: "陈明勇" , Content: "..." }, }) if err != nil { panic (err) } fmt. Println ( len (manyResult.InsertedIDs) == 2 ) // true } |
InsertMany
方法与官方的 API
同名,作用是插入多条数据。如果我们想要设置 options
参数,应使用 ManyOptions
方法。
Finder 查询器
Finder
是一个查询器,用于执行查询相关的操作。
查询单个文档
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
// https://github.com/chenmingyong0423/blog/blob/master/tutorial-code/go-mongox/collection/finder/find_one.go package main import ( "chenmingyong0423/blog/tutorial-code/go-mongox/collection" "context" "fmt" "github.com/chenmingyong0423/go-mongox" "github.com/chenmingyong0423/go-mongox/bsonx" "github.com/chenmingyong0423/go-mongox/builder/query" "go.mongodb.org/mongo-driver/mongo/options" ) func main() { // 你需要预先创建一个 *mongo.Collection 对象 mongoCollection := collection.NewCollection() // 使用 Post 结构体作为泛型参数创建一个 collection postCollection := mongox.NewCollection[collection.Post](mongoCollection) _, err := postCollection.Creator().InsertOne(context.Background(), collection.Post{Id: "1" , Title: "go" , Author: "陈明勇" , Content: "..." }) if err != nil { panic (err) } // 查询单个文档 post, err := postCollection.Finder().Filter(bsonx.Id( "1" )).FindOne(context.Background()) if err != nil { panic (err) } fmt. Println (post) // 设置 *options.FindOneOptions 参数 post2, err := postCollection.Finder(). Filter(bsonx.Id( "1" )). OneOptions(options.FindOne().SetProjection(bsonx.M( "content" , 0 ))). FindOne(context.Background()) if err != nil { panic (err) } fmt. Println (post2) // - map 作为 filter 条件 post3, err := postCollection.Finder().Filter( map [ string ]any{ "_id" : "1" }).FindOne(context.Background()) if err != nil { panic (err) } fmt. Println (post3) // - 复杂条件查询 // -- 使用 query 包构造复杂的 bson: bson.D{bson.E{Key: "title", Value: bson.M{"$eq": "go"}}, bson.E{Key: "author", Value: bson.M{"$eq": "陈明勇"}}} post4, err := postCollection.Finder(). Filter(query.BsonBuilder().Eq( "title" , "go" ).Eq( "author" , "陈明勇" ).Build()). FindOne(context.Background()) if err != nil { panic (err) } fmt. Println (post4) } |
基于 postCollection
实例,我们可以通过 Finder()
方法创建一个查询器,然后进行查询操作。
FindOne
方法与官方的 API
同名,作用是查询单个文档。我们可以通过 Filter
和 OneOptions
方法分别设置 查询条件 和 options
参数。
对于简单的查询条件,我们可以使用 bsonx
包提供的函数进行构造,例如 bsonx.Id("1")
;对于复杂的查询条件,我们可以使用 query
包提供的 BsonBuilder
构造器进行构造。这两个包的用法接下来会进行详细地介绍。
查询多个文档
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
// https://github.com/chenmingyong0423/blog/blob/master/tutorial-code/go-mongox/collection/finder/find.go package main import ( "chenmingyong0423/blog/tutorial-code/go-mongox/collection" "context" "fmt" "github.com/chenmingyong0423/go-mongox" "github.com/chenmingyong0423/go-mongox/bsonx" "github.com/chenmingyong0423/go-mongox/builder/query" "go.mongodb.org/mongo-driver/mongo/options" ) func main() { // 你需要预先创建一个 *mongo.Collection 对象 mongoCollection := collection.NewCollection() // 使用 Post 结构体作为泛型参数创建一个 collection postCollection := mongox.NewCollection[collection.Post](mongoCollection) _, err := postCollection.Creator().InsertMany(context.Background(), []collection.Post{ {Id: "1" , Title: "go" , Author: "陈明勇" , Content: "..." }, {Id: "2" , Title: "mongo" , Author: "陈明勇" , Content: "..." }, }) if err != nil { panic (err) } // 查询多个文档 // bson.D{bson.E{Key: "_id", Value: bson.M{"$in": []string{"1", "2"}}}} posts, err := postCollection.Finder().Filter(query.BsonBuilder().InString( "_id" , [] string { "1" , "2" }...).Build()).Find(context.Background()) if err != nil { panic (err) } for _, post := range posts { fmt. Println (post) } // 设置 *options.FindOptions 参数 // bson.D{bson.E{Key: "_id", Value: bson.M{types.In: []string{"1", "2"}}}} posts2, err := postCollection.Finder(). Filter(query.BsonBuilder().InString( "_id" , [] string { "1" , "2" }...).Build()). Options(options.Find().SetProjection(bsonx.M( "content" , 0 ))). Find(context.Background()) if err != nil { panic (err) } for _, post := range posts2 { fmt. Println (post) } } |
Find
方法与官方的 API
同名,作用是查询多个文档。如果我们想要设置 options
参数,应使用 Options
方法。
在上面的例子中,为了构造 $in
查询语句,我们使用了 BsonBuilder
提供的方法 InString
。
Updater 更新器
Updater
是一个更新器,用于执行更新相关的操作。
更新单个文档
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
// https://github.com/chenmingyong0423/blog/blob/master/tutorial-code/go-mongox/collection/updater/update_one.go package main import ( "chenmingyong0423/blog/tutorial-code/go-mongox/collection" "context" "fmt" "github.com/chenmingyong0423/go-mongox" "github.com/chenmingyong0423/go-mongox/bsonx" "github.com/chenmingyong0423/go-mongox/builder/update" "github.com/chenmingyong0423/go-mongox/types" "go.mongodb.org/mongo-driver/mongo/options" ) func main() { // 你需要预先创建一个 *mongo.Collection 对象 mongoCollection := collection.NewCollection() // 使用 Post 结构体作为泛型参数创建一个 collection postCollection := mongox.NewCollection[collection.Post](mongoCollection) _, err := postCollection.Creator().InsertOne(context.Background(), collection.Post{Id: "1" , Title: "go" , Author: "陈明勇" , Content: "..." }) if err != nil { panic (err) } // 更新单个文档 // 通过 update 包构建 bson 更新语句 updateResult, err := postCollection.Updater(). Filter(bsonx.Id( "1" )). Updates(update.BsonBuilder().Set(bsonx.M( "title" , "golang" )).Build()). UpdateOne(context.Background()) if err != nil { panic (err) } fmt. Println (updateResult.ModifiedCount == 1 ) // true // - 使用 map 构造更新数据,并设置 *options.UpdateOptions,执行 upsert 操作 updateResult2, err := postCollection.Updater(). Filter(bsonx.Id( "2" )). UpdatesWithOperator(types.Set, map [ string ]any{ "title" : "mongo" }).Options(options.Update().SetUpsert( true )). UpdateOne(context.Background()) if err != nil { panic (err) } fmt. Println (updateResult2.UpsertedID.( string ) == "2" ) // true } |
基于 postCollection
实例,我们可以通过 Updater()
方法创建一个更新器,然后进行更新操作。
UpdateOne
方法与官方的 API
同名,作用是更新单个文档。我们可以通过 Filter
和 Options
方法分别设置 文档匹配的条件 和 options
参数。
对于更新操作参数,我们可以使用以下两个方法进行设置:
Updates
方法:该方法接收bson
或map
等合法的更新操作语句。上面的例子使用了update
包里的BsonBuilder
对更新操作语句进行构造。UpdatesWithOperator
方法:该方法的第一个参数为更新操作符,第二个参数为预期更新的数据。
更新多个文档
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
// https://github.com/chenmingyong0423/blog/blob/master/tutorial-code/go-mongox/collection/updater/update_many.go package main import ( "chenmingyong0423/blog/tutorial-code/go-mongox/collection" "context" "fmt" "github.com/chenmingyong0423/go-mongox" "github.com/chenmingyong0423/go-mongox/bsonx" "github.com/chenmingyong0423/go-mongox/builder/query" "github.com/chenmingyong0423/go-mongox/builder/update" ) func main() { // 你需要预先创建一个 *mongo.Collection 对象 mongoCollection := collection.NewCollection() // 使用 Post 结构体作为泛型参数创建一个 collection postCollection := mongox.NewCollection[collection.Post](mongoCollection) _, err := postCollection.Creator().InsertMany(context.Background(), []collection.Post{ {Id: "1" , Title: "go" , Author: "陈明勇" , Content: "..." }, {Id: "2" , Title: "mongo" , Author: "陈明勇" , Content: "..." }, }) if err != nil { panic (err) } // 更新多个文档 updateResult, err := postCollection.Updater(). Filter(query.BsonBuilder().InString( "_id" , [] string { "1" , "2" }...).Build()). Updates(update.BsonBuilder().Set(bsonx.M( "title" , "golang" )).Build()). UpdateMany(context.Background()) if err != nil { panic (err) } fmt. Println (updateResult.ModifiedCount == 2 ) // true } |
UpdateMany
方法与官方的 API
同名,作用是更新多个文档。
Deleter 删除器
Deleter
是一个删除器,用于执行删除相关的操作。
删除单个文档
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
// https://github.com/chenmingyong0423/blog/blob/master/tutorial-code/go-mongox/collection/deleter/delete_one.go package main import ( "chenmingyong0423/blog/tutorial-code/go-mongox/collection" "context" "fmt" "github.com/chenmingyong0423/go-mongox" "github.com/chenmingyong0423/go-mongox/bsonx" "go.mongodb.org/mongo-driver/mongo/options" ) func main() { // 你需要预先创建一个 *mongo.Collection 对象 mongoCollection := collection.NewCollection() // 使用 Post 结构体作为泛型参数创建一个 collection postCollection := mongox.NewCollection[collection.Post](mongoCollection) _, err := postCollection.Creator().InsertMany(context.Background(), []collection.Post{ {Id: "1" , Title: "go" , Author: "陈明勇" , Content: "..." }, {Id: "2" , Title: "mongo" , Author: "陈明勇" , Content: "..." }, }) if err != nil { panic (err) } // 删除单个文档 deleteResult, err := postCollection.Deleter().Filter(bsonx.Id( "1" )).DeleteOne(context.Background()) if err != nil { panic (err) } fmt. Println (deleteResult.DeletedCount == 1 ) // true // 携带 option 参数 deleteResult2, err := postCollection.Deleter().Filter(bsonx.Id( "2" )).Options(options. Delete ().SetComment( "test" )).DeleteOne(context.Background()) if err != nil { panic (err) } fmt. Println (deleteResult2.DeletedCount == 1 ) // true } |
基于 postCollection
实例,我们可以通过 Deleter()
方法创建一个删除器,然后进行删除操作。
DeleteOne
方法与官方的 API
同名,作用是删除单个文档。我们可以通过 Filter
和 Options
方法分别设置 文档匹配的条件 和 options
参数。
删除多个文档
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
// https://github.com/chenmingyong0423/blog/blob/master/tutorial-code/go-mongox/collection/deleter/delete_many.go package main import ( "chenmingyong0423/blog/tutorial-code/go-mongox/collection" "context" "fmt" "github.com/chenmingyong0423/go-mongox" "github.com/chenmingyong0423/go-mongox/builder/query" ) func main() { // 你需要预先创建一个 *mongo.Collection 对象 mongoCollection := collection.NewCollection() // 使用 Post 结构体作为泛型参数创建一个 collection postCollection := mongox.NewCollection[collection.Post](mongoCollection) _, err := postCollection.Creator().InsertMany(context.Background(), []collection.Post{ {Id: "1" , Title: "go" , Author: "陈明勇" , Content: "..." }, {Id: "2" , Title: "mongo" , Author: "陈明勇" , Content: "..." }, }) if err != nil { panic (err) } // 删除多个文档 // - 通过 query 包构造复杂的 bson 语句 deleteResult, err := postCollection.Deleter().Filter(query.BsonBuilder().InString( "_id" , [] string { "1" , "2" }...).Build()).DeleteMany(context.Background()) if err != nil { panic (err) } fmt. Println (deleteResult.DeletedCount == 2 ) // true } |
DeleteMany
方法与官方的 API
同名,作用是删除多个文档。
Aggregator 聚合器
Aggregator
是一个聚合器,用于执行聚合相关的操作。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
// https://github.com/chenmingyong0423/blog/blob/master/tutorial-code/go-mongox/collection/aggregator/aggregator.go package main import ( "chenmingyong0423/blog/tutorial-code/go-mongox/collection" "context" "fmt" "github.com/chenmingyong0423/go-mongox" "github.com/chenmingyong0423/go-mongox/bsonx" "github.com/chenmingyong0423/go-mongox/builder/aggregation" "github.com/chenmingyong0423/go-mongox/types" "go.mongodb.org/mongo-driver/mongo" ) func main() { // 你需要预先创建一个 *mongo.Collection 对象 mongoCollection := collection.NewCollection() // 使用 Post 结构体作为泛型参数创建一个 collection postCollection := mongox.NewCollection[collection.Post](mongoCollection) _, err := postCollection.Creator().InsertMany(context.Background(), []collection.Post{ {Id: "1" , Title: "go" , Author: "陈明勇" , Content: "..." }, {Id: "2" , Title: "mongo" , Author: "陈明勇" , Content: "..." }, }) if err != nil { panic (err) } // 聚合操作 // - 使用 aggregation 包构造 pipeline posts, err := postCollection. Aggregator().Pipeline(aggregation.StageBsonBuilder().Project(bsonx.M( "content" , 0 )).Build()). Aggregate(context.Background()) if err != nil { panic (err) } for _, post := range posts { fmt. Println (post) } // 如果我们通过聚合操作更改字段的名称,那么我们可以使用 AggregationWithCallback 方法,然后通过 callback 函数将结果映射到我们预期的结构体中 type DiffPost struct { Id string `bson: "_id" ` Title string `bson: "title" ` Name string `bson: "name" ` // author → name Content string `bson: "content" ` Outstanding bool `bson: "outstanding" ` } result := make ([]*DiffPost, 0 ) // 将 author 字段更名为 name,排除 content 字段,添加 outstanding 字段,返回结果为 []*DiffPost err = postCollection.Aggregator(). Pipeline(aggregation.StageBsonBuilder().Project( bsonx.D(types.KV( "name" , "$author" ), types.KV( "author" , 1 ), types.KV( "_id" , 1 ), types.KV( "title" , 1 ), types.KV( "outstanding" , aggregation.BsonBuilder().Eq( "$author" , "陈明勇" ).Build()))).Build(), ). AggregateWithCallback(context.Background(), func (ctx context.Context, cursor *mongo.Cursor) error { return cursor.All(ctx, &result) }) for _, post := range result { fmt. Println (post) } } |
基于 postCollection
实例,我们可以通过 Aggregator()
方法创建一个聚合器,然后进行聚合操作。
我们可以通过 Pipeline
和 AggregateOptions
方法分别设置 pipeline
和 options
参数。
对于执行聚合操作,有以下两个方法:
Aggregate
方法:与与官方的API
同名。AggregateWithCallback
方法:因为我们在创建collection
装饰器时,使用泛型绑定了一个结构体,如果我们执行聚合操作之后,返回的数据与所绑定的结构体映射不上,这时可以使用该方法将结果映射到指定的结构里。
Builder 构造器
go-mongox
框架提供了以下几种类型的构造器:
universal
: 简单而又通用的bson
数据构造函数。query
: 查询构造器,用于构造查询操作所需的bson
数据。update
: 更新构造器,用于构造更新操作所需的bson
数据。aggregation
: 聚合操作构造器,包含两种,一种是用于构造聚合stage
阶段所需的bson
数据,另一种是用于构造除了stage
阶段以外的bson
数据。
universal 通用构造
我们可以使用 bsonx
包里的一些函数进行 bson
数据的构造,例如 bsonx.M
、bsonx.Id
和 bsonx.D
等等。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
// https://github.com/chenmingyong0423/blog/blob/master/tutorial-code/go-mongox/builder/universal.go package main import ( "fmt" "github.com/chenmingyong0423/go-mongox/bsonx" ) func main() { // bson.M{"姓名": "陈明勇"} m := bsonx.M( "姓名" , "陈明勇" ) fmt.Printf( "%#v\n\n" , m) // bson.M{"_id": "陈明勇"} id := bsonx.Id( "陈明勇" ) fmt.Printf( "%#v\n\n" , id) // bson.D{bson.E{Key:"姓名", Value:"陈明勇"}, bson.E{Key:"手机号", Value:"1888***1234"}} d := bsonx.D(bsonx.KV( "姓名" , "陈明勇" ), bsonx.KV( "手机号" , "1888***1234" )) fmt.Printf( "%#v\n\n" , d) // bson.E{Key:"姓名", Value:"陈明勇"} e := bsonx.E( "姓名" , "陈明勇" ) fmt.Printf( "%#v\n\n" , e) // bson.A{"陈明勇", "1888***1234"} a := bsonx.A( "陈明勇" , "1888***1234" ) fmt.Printf( "%#v" , a) } |
bsonx
包暂时提供了这些构造函数,后面会持续添加更多有用的函数。
特别注意的是,使用 bsonx.D
方法构造数据时,传入的参数,需要使用 bsonx.KV
方法进行传递,目的是强约束 key-value
的类型。
query 查询构造器
query
包可以帮我们构造出查询相关的 bson
数据,例如 $in
、$gt
、$and
等等。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
// https://github.com/chenmingyong0423/blog/blob/master/tutorial-code/go-mongox/builder/query.go package main import ( "fmt" "github.com/chenmingyong0423/go-mongox/bsonx" "github.com/chenmingyong0423/go-mongox/builder/query" ) func main() { // bson.D{bson.E{Key:"姓名", Value:"陈明勇"}} d := query.BsonBuilder().Add(bsonx.KV( "姓名" , "陈明勇" )).Build() fmt.Printf( "%#v\n\n" , d) // bson.D{bson.E{Key:"age", Value:bson.D{{Key:"$gt", Value:18}, bson.E{Key:"$lt", Value:25}}}} d = query.BsonBuilder().Gt( "age" , 18 ).Lt( "age" , 25 ).Build() fmt.Printf( "%#v\n\n" , d) // bson.D{bson.E{Key:"age", Value:bson.D{{Key:"$in", Value:[]int{18, 19, 20}}}}} d = query.BsonBuilder().InInt( "age" , 18 , 19 , 20 ).Build() fmt.Printf( "%#v\n\n" , d) // bson.d{bson.E{Key: "$and", Value: []any{bson.D{{Key: "x", Value: bson.D{{Key: "$ne", Value: 0}}}}, bson.D{{Key: "y", Value: bson.D{{Key: "$gt", Value: 0}}}}}} d = query.BsonBuilder().And( query.BsonBuilder().Ne( "x" , 0 ).Build(), query.BsonBuilder().Gt( "y" , 0 ).Build(), ).Build() fmt.Printf( "%#v\n\n" , d) // bson.D{bson.E{Key:"qty", Value:bson.D{{Key:"$exists", Value:true}, bson.E{Key:"$nin", Value:[]int{5, 15}}}}} d = query.BsonBuilder().Exists( "qty" , true ).NinInt( "qty" , 5 , 15 ).Build() fmt.Printf( "%#v\n\n" , d) // elemMatch // bson.D{bson.E{Key: "result", Value: bson.D{bson.E{Key: "$elemMatch", Value: bson.D{bson.E{Key: "$gte", Value: 80}, bson.E{Key: "$lt", Value: 85}}}}}} d = query.BsonBuilder().ElemMatch( "result" , bsonx.D(bsonx.KV( "$gte" , 80 ), bsonx.KV( "$lt" , 85 ))).Build() fmt.Printf( "%#v" , d) } |
query
包提供的方法不止这些,以上只是列举出一些典型的例子,还有更多的用法等着你去探索。
update 更新构造器
update
包可以帮我们构造出更新操作相关的 bson
数据,例如 $set
、$$inc
、$push
等等。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
// https://github.com/chenmingyong0423/blog/blob/master/tutorial-code/go-mongox/builder/update.go package main import ( "fmt" "github.com/chenmingyong0423/go-mongox/bsonx" "github.com/chenmingyong0423/go-mongox/builder/update" ) func main() { // bson.D{bson.E{Key:"$set", Value:bson.M{"name":"陈明勇"}}} u := update.BsonBuilder().Set(bsonx.M( "name" , "陈明勇" )).Build() fmt.Printf( "%#v\n\n" , u) // bson.D{bson.E{Key:"$inc", Value:bson.D{bson.E{Key:"orders", Value:1}, bson.E{Key:"ratings", Value:-1}}}} u = update.BsonBuilder().Inc(bsonx.D(bsonx.KV( "orders" , 1 ), bsonx.KV( "ratings" , - 1 ))).Build() fmt.Printf( "%#v\n\n" , u) // bson.D{bson.E{Key:"$push", Value:bson.M{"scores":95}}} u = update.BsonBuilder().Push(bsonx.M( "scores" , 95 )).Build() fmt.Printf( "%#v\n\n" , u) // bson.D{bson.E{Key:"$unset", Value:bson.D{primitive.E{Key:"quantity", Value:""}, bson.E{Key:"instock", Value:""}}}} u = update.BsonBuilder().Unset( "quantity" , "instock" ).Build() fmt.Printf( "%#v" , u) } |
update
包提供的方法不止这些,以上只是列举出一些典型的例子,还有更多的用法等着你去探索。
aggregation 聚合构造器
aggregation
包提供了两个 builder
:
StageBsonBuilder
:用于构造stage
阶段所需的bson
数据BsonBuilder
:用于构造除了stage
阶段以外的bson
数据。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
// https://github.com/chenmingyong0423/blog/blob/master/tutorial-code/go-mongox/builder/aggregation.go package main import ( "fmt" "github.com/chenmingyong0423/go-mongox/bsonx" "github.com/chenmingyong0423/go-mongox/builder/aggregation" "github.com/chenmingyong0423/go-mongox/builder/query" "github.com/chenmingyong0423/go-mongox/types" ) func main() { // bson.D{bson.E{Key:"$gt", Value:[]any{"$qty", 250}}} gt := aggregation.BsonBuilder().Gt( "$qty" , 250 ).Build() fmt.Printf( "%#v\n\n" , gt) // mongo.Pipeline{bson.D{bson.E{Key:"$project", Value:bson.D{bson.E{Key:"name", Value:1}, bson.E{Key:"age", Value:1}, bson.E{Key:"qtyGt250", Value:bson.D{bson.E{Key:"$gt", Value:[]interface {}{"$qty", 250}}}}}}}} pipeline := aggregation.StageBsonBuilder().Project(bsonx.D(bsonx.KV( "name" , 1 ), bsonx.KV( "age" , 1 ), bsonx.KV( "qtyGt250" , gt))).Build() fmt.Printf( "%#v\n\n" , pipeline) // bson.D{bson.E{Key:"$or", Value:[]interface {}{bson.D{bson.E{Key:"score", Value:bson.D{bson.E{Key:"$gt", Value:70}, bson.E{Key:"$lt", Value:90}}}}, bson.D{bson.E{Key:"views", Value:bson.D{bson.E{Key:"$gte", Value:90}}}}}}} or := aggregation.BsonBuilder().Or( query.BsonBuilder().Gt( "score" , 70 ).Lt( "score" , 90 ).Build(), query.BsonBuilder().Gte( "views" , 90 ).Build(), ).Build() fmt.Printf( "%#v\n\n" , or) // mongo.Pipeline{bson.D{bson.E{Key:"$match", Value:bson.D{bson.E{Key:"$or", Value:[]any{bson.D{bson.E{Key:"score", Value:bson.D{bson.E{Key:"$gt", Value:70}, bson.E{Key:"$lt", Value:90}}}}, bson.D{bson.E{Key:"views", Value:bson.D{bson.E{Key:"$gte", Value:90}}}}}}}}}, bson.D{bson.E{Key:"$group", Value:bson.D{bson.E{Key:"_id", Value:any(nil)}, bson.E{Key:"count", Value:bson.D{bson.E{Key:"$sum", Value:1}}}}}}} pipeline = aggregation.StageBsonBuilder().Match(or).Group( nil , bsonx.E( "count" , aggregation.BsonBuilder().Sum( 1 ).Build())).Build() fmt.Printf( "%#v\n\n" , pipeline) // mongo.Pipeline{bson.D{bson.E{Key:"$unwind", Value:"$size"}}} pipeline = aggregation.StageBsonBuilder().Unwind( "$size" , nil ).Build() fmt.Printf( "%#v\n\n" , pipeline) // mongo.Pipeline{bson.D{bson.E{Key:"$unwind", Value:bson.D{bson.E{Key:"path", Value:"$size"}, bson.E{Key:"includeArrayIndex", Value:"arrayIndex"}, bson.E{Key:"preserveNullAndEmptyArrays", Value:true}}}}} pipeline = aggregation.StageBsonBuilder().Unwind( "$size" , &types.UnWindOptions{ IncludeArrayIndex: "arrayIndex" , PreserveNullAndEmptyArrays: true , }).Build() fmt.Printf( "%#v" , pipeline) } |
aggregation
包提供的方法不止这些,以上只是列举出一些典型的例子,还有更多的用法等着你去探索。
小结
本文对 go-mongox
框架进行了详细的介绍,它有两个核心,一个是基于泛型的 colletion
形态,另一个就是 bson
构造器了。这两个核心是单独存在的,你可以使用其中之一,也可以同时使用。
仓库地址:https://github.com/chenmingyong0423/go-mongox
该框架处于初期阶段,希望通过集思广益的方式,邀请各位开发者共同参与,提出宝贵的建议和意见,共同打造一个更强大、更灵活的框架。期待着您的积极参与和宝贵反馈,共同推动go-mongox
不断进步。
以上就是go mongox简洁高效文档操作及bson数据构造流畅技巧的详细内容,更多关于go mongox文档操作bson构造的资料请关注脚本之家其它相关文章!
文章来自互联网,只做分享使用。发布者:叮当,转转请注明出处:https://www.dingdanghao.com/article/42427.html