【Go - mongodb - bson / schema】
Bson是什么
bson
是 MongoDB 使用的一种二进制编码格式,全称为 Binary JSON。它用于存储和传输 JSON 风格的文档数据。bson
提供了一种高效的方式来表示 JSON 数据,同时支持更多的数据类型,例如日期和二进制数据。
在 Go 语言中,bson
是由 MongoDB 官方驱动包 go.mongodb.org/mongo-driver/bson
提供的一个包,用于处理 BSON 数据。这个包提供了多种类型和函数来编码和解码 BSON 数据。
Bson常用类型与示例
bson.D
:有序的 BSON 文档,适用于需要保持字段顺序的场景。bson.M
:无序的 BSON 文档,适用于不需要保持字段顺序的场景。bson.A
:BSON 数组,适用于表示数组的场景。bson.E
:键值对,常用于构建bson.D
。
以下是一个包含bson.D,bson.M,bson.A,bson.E的示例
package mainimport ("context""fmt""log""time""go.mongodb.org/mongo-driver/bson""go.mongodb.org/mongo-driver/mongo""go.mongodb.org/mongo-driver/mongo/options"
)func main() {// 连接到 MongoDBclient, err := mongo.Connect(context.TODO(), options.Client().ApplyURI("mongodb://localhost:27017"))if err != nil {log.Fatal(err)}defer client.Disconnect(context.TODO())// 选择数据库和集合collection := client.Database("testdb").Collection("users")// 使用 bson.D 构建查询filterD := bson.D{{Key: "name", Value: "John"},{Key: "age", Value: bson.D{{Key: "$gt", Value: 25},}},}// 使用 bson.M 构建查询filterM := bson.M{"name": "John","age": bson.M{"$gt": 25,},}// 使用 bson.D 构建查询,包含 bson.E 和 bson.AfilterA := bson.D{{Key: "name", Value: "John"},{Key: "tags", Value: bson.A{"developer", "golang"}},}// 查询数据var resultsD []bson.Mvar resultsM []bson.Mvar resultsA []bson.Mctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)defer cancel()// bsonDcursorD, err := collection.Find(ctx, filterD)if err != nil {log.Fatal(err)}defer cursorD.Close(ctx)// bsonMcursorM, err := collection.Find(ctx, filterM)if err != nil {log.Fatal(err)}defer cursorM.Close(ctx)// bsonE// bsonAcursorA, err := collection.Find(ctx, filterA)defer cursorA.Close(ctx)if err = cursorD.All(ctx, &resultsD); err != nil {log.Fatal(err)}if err = cursorM.All(ctx, &resultsM); err != nil {log.Fatal(err)}if err = cursorA.All(ctx, &resultsA); err != nil {log.Fatal(err)}// 打印结果fmt.Println("Results using bson.D:", resultsD)fmt.Println("Results using bson.M:", resultsM)fmt.Println("Results using bson.D with bson.A:", resultsA)
}
如何定义表结构schema
虽然MongoDB 是no-sql类型,但在使用的时候,表结构一般是固定的,且在代码中为了更清晰的展示表结构 以及 其字段。所以一般都是 定义声明其schema,以下是个示例,
package mainimport ("context""fmt""log""sync""time""go.mongodb.org/mongo-driver/bson""go.mongodb.org/mongo-driver/bson/primitive""go.mongodb.org/mongo-driver/mongo""go.mongodb.org/mongo-driver/mongo/options"
)// User 表结构定义
type User struct {// 使用omitempty来表示某些字段是可选的ID primitive.ObjectID `bson:"_id,omitempty"`Name string `bson:"name"`Age int `bson:"age"`Email string `bson:"email,omitempty"`
}// 获取MongoDB客户端的单例
var singlestonMongoClient *mongo.Client
var once sync.Oncefunc getSinglestonMongoClient() *mongo.Client {once.Do(func() {uri := "mongodb://localhost:27017"client, err := mongo.Connect(context.TODO(), options.Client().ApplyURI(uri))if err != nil {panic(err)}singlestonMongoClient = client})return singlestonMongoClient
}func main() {client := getSinglestonMongoClient()if client == nil {panic("client is nil")}defer func() {if err := client.Disconnect(context.TODO()); err != nil {panic(err)}}()// 选择数据库和集合collection := client.Database("testdb").Collection("users")// 查询用户数据var users []Userctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)defer cancel()cursor, err := collection.Find(ctx, bson.M{})if err != nil {log.Fatal(err)}defer cursor.Close(ctx)// 遍历数据for cursor.Next(ctx) {var user Userif err := cursor.Decode(&user); err != nil {log.Fatal(err)}users = append(users, user)}if err := cursor.Err(); err != nil {log.Fatal(err)}// 打印用户数据for _, user := range users {fmt.Printf("User: %+v\n", user)}
}