安装并使用依赖

安装MongoDB Go Driver

go get go.mongodb.org/mongo-driver

使用MongoDB Go Driver

package main

import (
    "context"
    "fmt"
    "log"

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

func main() {
    // 设置库地址
    clientOptions := options.Client().ApplyURI("mongodb://***.***.***.***:*****")

    // 连接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("test").Collection("new1")

    ···
    // 余下代码在此部分
    ···

    // 关闭数据库连接
    err = client.Disconnect(context.TODO())
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("Connection to MongoDB closed.")
}

关于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字段匹配小明或者小红的文档:

bson.D{{
    "name", bson.D{{
        "$in", 
        bson.A{"小明", "小红"}
    }}
}}

bson文档:go.mongodb.org/mongo-driver/bson


查找一个文档

要查询单个的文档, 使用collection.FindOne()。这个函数返回单个的结果,被解码成为一个值。

// 存放查询结果的map[string]interface{}
var result map[string]interface{}

err = collection.FindOne(context.TODO(), bson.D{{}}).Decode(&result)

if err != nil {
    log.Fatal(err)
}

// 打印result
fmt.Printf("results: %v\n", result)

查找多个文档

要查询多个文档,使用collection.Find(),这个函数返回一个游标。一个游标提供一个文档流, 通过它你可以遍历和解码每一个文档。一旦一个游标被消耗掉,你应该关闭游标。这里你也可以使用options包来设定一些操作选项,特别的,你可以设定一个返回文档数量的限制, 比如3个。

findOptions := options.Find()
// 配置查询属性,查询3条数据,若全部查询则可以屏蔽此行
findOptions.SetLimit(3)

// 配置查询,bson.D{{}} 查询所有数据,不设置条件,查找多个文档将返回一个游标
cur, err := collection.Find(context.TODO(), bson.D{{}}, findOptions)

if err != nil {
    log.Fatal(err)
}

// 存放查询结果的interface集合
var results []interface{}

// 通过游标进行迭代使我们一次可以解码一个文档
for cur.Next(context.TODO()) {
    var item map[string]interface{}
    // 将数据decode到item
    err := cur.Decode(&item)
    if err != nil {
        log.Fatal(err)
    }
    // 将item的(指针)数据地址推入results,这里也可显式推入结果
    results = append(results, &item)
}

err = cur.Err()
if err != nil {
    log.Fatal(err)
}

// 完成后关闭游标
cur.Close(context.TODO())

// 打印results,为指针集合
fmt.Printf("results: %v\n", results)

插入一个文档

要插入一个单独的文档, 使用collection.InsertOne()函数

type People struct {
    Name   string
    Age    int
    Height int
}

people := People{"小明", 18, 180}

insertResult, err := collection.InsertOne(context.TODO(), people)

if err != nil {
    log.Fatal(err)
}

fmt.Println("Inserted one document: ", insertResult.InsertedID)

插入多个文档

插入多个文档使用collection.InsertMany(),函数会采用一个interface集合:

type People struct {
    Name   string
    Age    int
    Height int
}

people1 := People{"小明", 18, 180}
people2 := People{"小红", 17, 165}
people3 := People{"小花", 15, 157}

// 将三个值放入interface集合
people := []interface{}{people1, people2, people3}

insertManyResult, err := collection.InsertMany(context.TODO(), people)

if err != nil {
    log.Fatal(err)
}

fmt.Println("Inserted documents: ", insertManyResult.InsertedIDs)

更新文档

filter := bson.D{{"name", "小明"}}

// $set指令,直接修改。相应的还有$inc与原值做加法等
update := bson.D{
    {"$set", bson.D{
        {"age", 20},
    }},
}

updateResult, err := collection.UpdateOne(context.TODO(), filter, update)

if err != nil {
    log.Fatal(err)
}

fmt.Printf("Matched %v documents and updated %v documents.\n", updateResult.MatchedCount, updateResult.ModifiedCount)

删除这个集合

collection.Drop(context.TODO())

删除一条数据

使用collection.DeleteOne()

deleteResult, err := collection.DeleteMany(context.TODO(), bson.D{{"name", "小明"}})

if err != nil {
    log.Fatal(err)
}

fmt.Println("Deleted document: ", deleteResult.DeletedCount)

删除多条数据

使用collection.DeleteMany()

deleteResult, err := collection.DeleteMany(context.TODO(), bson.D{{}})

if err != nil {
    log.Fatal(err)
}

fmt.Println("Deleted documents: ", deleteResult.DeletedCount)

参考文档

MongoDB Go Driver使用帮助文档
mongodb官方的golang驱动基础使用
mongo-go-driver
go.mongodb.org/mongo-driver

Last modification:September 22, 2020
If you think my article is useful to you, please feel free to appreciate