使用MongoDB.com官方的Go驱动程序进行基本操作

有很多使用Mgo的例子,但是用官方的MongoDB.com驱动程序的例子很少。我觉得为了未来的自己,我应该记下来。我以StackOverflow的标签为准,将其命名为mongo-go。

我已将本次的源代码放在https://github.com/mkiuchi/go-mongo-driver-example。

Mgo与官方驱动程序的差异及信息来源的相关信息。

我沒有查過,所以不太清楚。雖然在官方有稍微提到,但我並不打算過多討論這個問題,所以如果你對此有興趣,請自行解決。

请查看MongoDB.com的驱动程序页面以获取有关官方驱动程序的信息。目前最新版本为1.0.3。尽管我认为GoDoc和教程可能是您最常看到的资源,但它们在详细程度上缺乏一些内容。这也是我决定撰写这篇文章的原因之一。

就像我之前说的那样,从我个人看来,StackOverflow是我见过的最好的信息来源,虽然很多时候缺乏互动,说实话不太可靠,但请大家自己努力去找答案。

安装

按照公式的指示操作即可安装。由于我的情况dep无法正常工作,所以我选择使用go get安装。

$ dep ensure -add "go.mongodb.org/mongo-driver/mongo@~1.0.0"
$ go get -u "go.mongodb.org/mongo-driver/mongo"
$ go get "go.mongodb.org/mongo-driver/bsontype"

连接

用以下的方法来做。以下的示例中,检查数据库连接并输出结果。

package main

import (
    "context"
    "fmt"
    "time"

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

func main() {
    // コンテキストの作成
    //   - バックグラウンドで接続する。タイムアウトは10秒
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    // 関数を抜けたらクローズするようにする
    defer cancel()
    // 指定したURIに接続する
    c, err := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://localhost:27017"))
    defer c.Disconnect(ctx)
    // DBにPingする
    err = c.Ping(ctx, readpref.Primary())
    if err != nil {
        fmt.Println("connection error:", err)
    } else {
        fmt.Println("connection success:")
    }
}

大多数的文章都会使用context.Background()来作为连接选项,但也有一些情况下会使用context.TODO()。总之,我认为使用context.Background()就可以了。

阅读开头

只需简单地搜索并读取一条数据

package main

import (
    "context"
    "fmt"
    "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"
)

func main() {
    // MongoDBの接続設定
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()
    c, _ := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://localhost:27017"))
    defer c.Disconnect(ctx)

    // 結果を格納する変数の構造定義
    type resultType struct {
        Rid     string
        Keyword string
    }

    // 結果を格納する変数を宣言
    var result resultType

    // MongoDBのCollectionを取得
    col := c.Database("rec").Collection("autorec")

    // 検索条件となるprimitive.ObjectID型の変数を指定
    objectID, _ := primitive.ObjectIDFromHex("5cffa613c74a91322fc7cbb2")

    // 検索を実行し、結果を変数 result に格納
    err := col.FindOne(context.Background(), bson.M{"_id": objectID}).Decode(&result)
    _ = err
    fmt.Println(result)
}

结果会变成以下的感觉

$ go run readone.go 
{abcd1234 オリンピック}

阅读多个搜索结果

package main

import (
    "context"
    "fmt"
    "time"

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

func main() {
    // MongoDBの接続設定
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()
    c, _ := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://localhost:27017"))
    defer c.Disconnect(ctx)

    // 結果を格納する変数の構造定義
    type resultType struct {
        Start int
        Title string
    }

    // MongoDBのCollectionを取得
    col := c.Database("rec").Collection("rec")

    // 検索条件となるint型の変数を指定
    location, _ := time.LoadLocation("Asia/Tokyo")
    start := time.Date(2019, 6, 30, 0, 0, 0, 0, location).Unix() * 1000
    end := time.Date(2019, 6, 30, 23, 59, 59, 99, location).Unix() * 1000
    fmt.Println(start, end)

    // 検索を実行
    cur, err := col.Find(context.Background(), bson.M{
        "start": bson.M{
            "$gte": start,
            "$lte": end,
        }})
    _ = err

    // 結果のカーソルをforで回して順番に結果を取得
    for cur.Next(context.Background()) {
        var ret resultType
        cur.Decode(&ret)
        fmt.Println(ret)
    }
}

结果将如下所示

$ go run readmany.go 
1561820400000 1561906799000
{1561879320000 プレマップ}
{1561880460000 フラッシュ天気}

插入文档(或记录)

package main

import (
    "context"
    "time"

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

func main() {
    // MongoDBの接続設定
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()
    c, _ := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://localhost:27017"))
    defer c.Disconnect(ctx)

    // 挿入するデータの構造を定義
    // 21, 22行目の末尾の文字はType aliasと呼ぶらしい。MongoDB内でフィールド名として解釈される
    type dataType struct {
        Rid     string `bson:"rid"`
        Keyword string `bson:"keyword"`
    }

    // 挿入するデータを作成
    data := dataType{
        Rid:     "俺のID",
        Keyword: "俺のキーワード",
    }

    // MongoDBのCollectionを取得
    col := c.Database("rec").Collection("autorec")

    // データを挿入
    col.InsertOne(context.Background(), data)

}

在上述的例子中,我们插入了一个结构体(struct),但是它也可以很好地处理其他类型(如map等)直接传入。

因为我从来没有尝试过批量插入多个数据,所以跳过这一步。

删除文档(=记录)

package main

import (
    "context"
    "fmt"
    "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"
)

func main() {
    // MongoDBの接続設定
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()
    c, _ := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://localhost:27017"))
    defer c.Disconnect(ctx)

    // MongoDBのCollectionを取得
    col := c.Database("rec").Collection("autorec")

    // 検索条件となるprimitive.ObjectID型の変数を指定
    objectID, _ := primitive.ObjectIDFromHex("5d1924916a81c3556cf3479b")

    // 検索を実行し、結果のドキュメントを削除
    _, err := col.DeleteOne(context.Background(), bson.M{"_id": objectID})
    if err != nil {
        fmt.Println("delete failed:", err)
    } else {
        fmt.Println("delete success")
    }
}

没有特别的评论。

广告
将在 10 秒后关闭
bannerAds