go操作MongoDB数据库

233 阅读3分钟

首先要下载与配置 MongoDB ,这里就不演示了

创建数据库

打开命令行

// 连接数据库
mongo 

// 创建数据库
use test

创建集合

集合就是数据表

// 会在test数据库中创建student数据表
db.createCollection("student");

下载驱动

go get go.mongodb.org/mongo-driver/mongo

go mod tidy

连接mongoDB

package main

import (
	"context"
	"fmt"
	"log"

	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
)

var client *mongo.Client

func initDB() {
	co := options.Client().ApplyURI("mongodb://localhost:27017")
	c, err := mongo.Connect(context.TODO(), co)
	if err != nil {
		log.Fatal(err)
	}

	err2 := c.Ping(context.TODO(), nil)
	if err != nil {
		log.Fatal(err2)
	} else {
		fmt.Println("连接成功")
	}
        client = c
}

func main() {
	initDB()
}

BSON简介

MongoDB 中的 JSON 文档存储在名为 BSON (二进制编码的 JSON )的二进制表示中。与其他将 JSON 数据存储为简单字符串和数字的数据库不同, BSON 编码扩展了JSON 表示,使其包含额外的类型,如 int、long、date、浮点数和decimal128 。这使得应用程序更容易可靠地处理、排序和比较数据。

连接 MongoDBGo 驱动程序中有两大类型表示 BSON 数据: DRaw

类型 D 家族被用来简洁地构建使用本地 Go 类型的 BSON 对象。这对于构造传递给 MongoDB 的命令特别有用。D 家族包括四类:

  • D: 一个 BSON 文档,这种类型应该在顺序重要的情况下使用,比附 MongoBD 命令
  • M: 一张无序的 map ,它和 D 是一样的,只是它不保持顺序
  • A: 一个 BSON 数组
  • E: D 里面的一个元素

要使用 BSON ,需要导入下面的包

import "go.mongodb.org/mongo-driver/bson"

下面是使用 D 类型构建过滤器文档的例子

func main() {
	// 相当于filter 过滤器 sql中的where
	d := bson.D{{"name", "tom"}}
	fmt.Printf("d: %v\n", d)
}

Raw 类型用于验证字节切片,你还可以使用 Lookup() 从原始类型检索单个元素,如果你不想要将 BSON 反序列化成为另一种类型的开销,那么这是非常有用的,这里我们只使用 D 类型

添加文档

...
type Student struct {
	Name string
	Age  int
}

// 插入一个
func insert() {
	s1 := Student{
		Name: "tom",
		Age:  20,
	}

	// 连接文档(数据表)
	c := client.Database("test").Collection("student")
	ior, err := c.InsertOne(context.TODO(), s1)
	if err != nil {
		fmt.Printf("err: %v\n", err)
	} else {
		// 返回id ior.InsertedID: ObjectID("63a2d47b382d97e4821e9a0c")
		fmt.Printf("ior.InsertedID: %v\n", ior.InsertedID)
	}
}

// 插入多个
func insertMany() {
	c := client.Database("test").Collection("student")
	s1 := Student{
		Name: "tom",
		Age:  20,
	}
	s2 := Student{
		Name: "rose",
		Age:  21,
	}
	stus := []interface{}{s1, s2}
	imr, err := c.InsertMany(context.TODO(), stus)
	if err != nil {
		fmt.Printf("err: %v\n", err)
	}
	// 输出插入的id imr.InsertedIDs: [ObjectID("63a2d607f29687c5f06de0a5") ObjectID("63a2d607f29687c5f06de0a6")]
	fmt.Printf("imr.InsertedIDs: %v\n", imr.InsertedIDs)
}

func main() {
	initDB()
	// insert()
	insertMany()
}

查找文档

...

// 查询
func find() {
	ctx := context.TODO()
	defer client.Disconnect(ctx)
	// 连接文档(数据表)
	c := client.Database("test").Collection("student")

	// c2为游标
	// 查询全部
	// c2, err := c.Find(ctx, bson.D{})
	// 查询name为tom的数据
	c2, err := c.Find(ctx, bson.D{{"name", "tom"}})
	if err != nil {
		log.Fatal(err)
	}
	defer c2.Close(ctx)

	for c2.Next(ctx) {
		var result bson.D
                // 解码读取到的数据
		c2.Decode(&result)
		fmt.Printf("result: %v\n", result)
		fmt.Printf("result.Map(): %v\n", result.Map())
	}
}

func main() {
	initDB()
	find()
}

更新文档

...

func update() {
	ctx := context.TODO()
	defer client.Disconnect(ctx)
	c := client.Database("test").Collection("student")

	// 把文档中name为tom的数据改为 update 中的内容
	// 如果在文档中找不到对应的字段name age 会创建字段并且把数据放进去
	update := bson.D{{"$set", bson.D{{"name", " tom"}, {"age", 22}}}}

	// c.UpdateByID()
	// c.UpdateOne()
	ur, err := c.UpdateMany(ctx, bson.D{{"name", "big tom"}}, update)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("ur.ModifiedCount: %v\n", ur.ModifiedCount)
}

func main() {
	initDB()
	update()
}

删除文档

...

func delete() {
	ctx := context.TODO()
	defer client.Disconnect(ctx)
	c := client.Database("test").Collection("student")

	// 删除name为big tom的数据
	// c.DeleteOne()
	ur, err := c.DeleteMany(ctx, bson.D{{"name", "big tom"}})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("ur.DeletedCount: %v\n", ur.DeletedCount)
}

func main() {
	initDB()
	delete()
}