MongoDB
MongoDB是一个高性能,开源,无模式的文档型数据库,是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。他支持的数据结构非常松散,采用的是类似json的bjson格式来存储数据,因此可以存储比较复杂的数据类型。Mongo最大的特点是他支持的查询语言非常强大,其语法有点类似于面向 对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。
下表将帮助您更容易理解Mongo中的一些概念:
添加mongodb依赖
go get go.mongodb.org/mongo-driver/mongo
连接MongoDB:
1.链接数据库 func Connect(ctx context.Context, opts ...*options.ClientOptions)
Connect 需要两个参数,一个context和一个options.ClientOptions对象
简单的链接实例:
// 设置客户端选项 clientOptions := options.Client().ApplyURI("mongodb://user:password@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!")
上面代码的流程就是 创建 链接对象 option 和 context , 然后写入 mongo.Connect , Connect 函数返回一个链接对象 和一个错误 对象,如果错误对象不为空,那就链接失败了.
然后我们可以再次测试,链接:client.Ping(context.TODO(), nil)
cilent 对象 Ping 就好了,他会返回一个错误对象,如果不为空,就链接失败了
2.链接成功后,可以创建 数据表的 链接对象了:
collectionStudent := client.Database("mongodb_study").Collection("student")
mongodb_study 是数据库,student是数据表
3.断开链接对象 client.Disconnect()
如果我们不在使用 链接对象,那最好断开,减少资源消耗
err = client.Disconnect(context.TODO()) if err != nil { log.Fatal(err) } fmt.Println("Connection to MongoDB closed.")
操作数据库
CRUD操作
命令行输入mongo -u"xxx" -p"xxx" 进入mongodb
插入文档
插入单个文档
collection.InsertOne()
type Student struct { Name string Age int } collectionStudent:= client.Database("mongodb_study").Collection("student") stu1:=Student{"李四",133} _,err = collectionStudent.InsertOne(context.TODO(),stu1) if err != nil { log.Println(err) }
插入多条文档
collection.InsertMany()
不同的是接受一个 切片作为数据集合:
type Student struct { Name string Age int } students :=[]interface{}{Student{"张三",12},Student{"李四",123}} _, err = collectionStudent.InsertMany(context.TODO(), students) CheckErr(err)
命令行查看验证:
> db.student.find() { "_id" : ObjectId("62458616ef2590a98db33852"), "name" : "hyy", "age" : 19 } { "_id" : ObjectId("62458928ea5a619827084efc"), "name" : "hyy", "age" : 19 } { "_id" : ObjectId("62458b503e218bd570a37fc8"), "name" : "hhh", "age" : 13 } { "_id" : ObjectId("62458e840ad555317b9a3917"), "name" : "张三", "age" : 12 } { "_id" : ObjectId("62458e840ad555317b9a3918"), "name" : "李四", "age" : 123 }
更新文档
更新单个文档
collection.UpdateOne()
如果有多个满足条件的,只更新第一条
// filter: 包含查询操作符的文档,可以用来选择要查询的文档 // 查询到name=hyy的文档 filter := bson.D{{"name", "hyy"}} // 修改name 为hhhh update := bson.D{ {"$set",bson.D{{"name", "hhhh"}}}, } collectionStudent.UpdateOne(context.TODO(), filter, update)
命令行查看验证:
> db.student.find() { "_id" : ObjectId("62458616ef2590a98db33852"), "name" : "hyy-new", "age" : 23 } { "_id" : ObjectId("62458928ea5a619827084efc"), "name" : "hyy", "age" : 19 } { "_id" : ObjectId("62458b503e218bd570a37fc8"), "name" : "hhh", "age" : 13 } { "_id" : ObjectId("62458e840ad555317b9a3917"), "name" : "张三", "age" : 12 } { "_id" : ObjectId("62458e840ad555317b9a3918"), "name" : "李四" }
// update := bson.M{"$set": Student{Name: "hyy-new"}} // 不推荐直接用结构体,玩意结构体字段多了,初始化为零值。 // 因为可能会吧零值更新到数据库,而不是像 gorm 的updates 忽略零值
更新多个文档
collection.UpdateMany()
{ "_id" : ObjectId("62458928ea5a619827084efc"), "name" : "hyy", "age" : 19 } { "_id" : ObjectId("6245a141b6731395285e0315"), "name" : "hyy", "age" : 22, "nike_name" : [ [ "1", "2" ] ] }
collectionStudent:= client.Database("mongodb_study").Collection("student") filter := bson.D{{"name", "hyy"}} update := bson.D{{"$inc", bson.D{ {"age", 1}, }, }} _, err = collectionStudent.UpdateMany(context.TODO(), filter, update) CheckErr(err)
命令行查询结果:
> db.student.find({"name":"hyy"}) { "_id" : ObjectId("62458928ea5a619827084efc"), "name" : "hyy", "age" : 20 } { "_id" : ObjectId("6245a141b6731395285e0315"), "name" : "hyy", "age" : 23, "nike_name" : [ [ "1", "2" ] ] }
查找文档
需要一个filter文档, 以及一个指针在它里边保存结果的解码
查询单个文档:
collection.FindOne()
type Student struct { Name string Age int } var s Student filter:=bson.D{{"name","hyy"}} err = collectionStudent.FindOne(context.TODO(), filter).Decode(&s) CheckErr(err) fmt.Println(s)
输出:
{hyy 20}
查询多个文档:
collection.Find()
{ "_id" : ObjectId("62458928ea5a619827084efc"), "name" : "hyy", "age" : 20 } { "_id" : ObjectId("6245a141b6731395285e0315"), "name" : "hyy", "age" : 23, "nike_name" : [ [ "1", "2" ] ] }
type Student struct { Name string Age int } filter:=bson.D{{"name","hyy"}} cursor, err := collectionStudent.Find(context.TODO(), filter) CheckErr(err) defer cursor.Close(context.TODO()) var students []Student err = cursor.All(context.TODO(), &students) CheckErr(err) for _, student := range students { fmt.Println(student) }
输出:
{hyy 20} {hyy 23}
删除文档
collection.DeleteOne() collection.DeleteMany()
如果bson.D{{ }}作为filter参数,这会匹配集合内所有的文档
filter:=bson.D{{"name","hyy"}} _, err = collectionStudent.DeleteMany(context.TODO(), filter) CheckErr(err)