使用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")
}
}
没有特别的评论。