使用Go从MongoDB获取文档
首先
我在使用WordPress经营博客,但希望将所有文章以Markdown格式保存,于是自己写了一个博客系统1。接近一年前,我被裁员离开了网络公司,现在从事不同的工作,所以我想趁机尝试一下不熟悉的技术,使用Go(echo)和MongoDB来开发这个系统。希望能够在这里记录下我的经验。我开始正式学习Go大约有3个月了,不太系统,更多是在阅读书籍/文档的同时实践,如果有错误的地方,请给予指正。
开发环境
-
- Windows10
-
- Visual Studio Code
-
- go version go1.15.5 windows/amd64
-
- MongoDB server version: 4.4.3
- go.mongodb.org/mongo-driver v1.4.5
开发环境在Windows上,但在CentOS7上已经确认可以运行。
蒙古数据库

use doblog
db.createUser( { user:"USER", pwd:"PASSWORD", roles:[{ "role" : "dbOwner", "db" : "doblog" }] } );
db.entries.createIndex({entryCode: 1},{unique: true});
db.entries.createIndex({entryId: 1},{unique: true});
db.entries.createIndex({isPublished: 1, publishDate: -1});
db.entries.createIndex({category: 1, isPublished: 1, publishDate: -1});
仅有一个选项的中文释义:
unique:true 表示该字段是唯一的。其他字段适用于 find 操作。可以通过 explain 来检查索引是否生效。
db.entries.find({category: "php", isPublished: 1}).sort({publishDate: -1}).limit(1).explain();
我在这里找到了参考资料。
从WordPress迁移数据是通过使用PHP编写的,但我已经简化了它。
mongo-driver -> mongodb 驱动程序
go get -u go.mongodb.org/mongo-driver/mongo
代码 mǎ)
package main
import (
"context"
"fmt"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
// Entry for get data from mongodb
type Entry struct {
EntryID int32 `bson:"entryId"`
EntryCode string `bson:"entryCode"`
PublishDate string `bson:"publishDate"`
Title string `bson:"title"`
Content string `bson:"content"`
Category []string `bson:"category"`
IsPublished int32 `bson:"isPublished"`
AuthorID int32 `bson:"authorId"`
CreatedAt string `bson:"createdAt"`
UpdatedAt string `bson:"updatedAt"`
}
func main() {
//
// mongodb init
//
ctx := context.Background()
credential := options.Credential{
AuthSource: "doblog",
Username: "USER",
Password: "PASSWORD",
}
client, err := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://127.0.0.1:27017").SetAuth(credential))
defer client.Disconnect(ctx)
//
// get entries (publishDateの降順でソート)
//
var entryList []Entry
entries := client.Database("doblog").Collection("entries")
// publishDateの降順
findOption := options.Find().SetSort(bson.D{{Key: "publishDate", Value: -1}})
// PaginatorなどでLimit, Offsetを使いたい場合はこう
// findOption := options.Find().SetSort(bson.D{{Key: "publishDate", Value: -1}}).SetSkip(10).SetLimit(5)
// SQLでの select * from entries where isPublished = 1 と同様
cur, err := entries.Find(ctx, bson.D{{Key: "isPublished", Value: 1}}, findOption)
if err != nil {
fmt.Println(err)
}
defer cur.Close(ctx)
// findはスライス等で返ってこない。 *Cursol型で返ってくるので下記のようにループ回して取得
for cur.Next(ctx) {
var result Entry
err := cur.Decode(&result)
if err != nil {
fmt.Println(err)
}
entryList = append(entryList, result)
}
fmt.Println(entryList)
//
// get entry (entryCodeを指定して一件取得)
//
var entry Entry
err = entries.FindOne(ctx, bson.D{{Key: "entryCode", Value: "net-core-3-0-excel-epplus"}, {Key: "isPublished", Value: 1}}).Decode(&entry)
if err != nil {
fmt.Println(err)
}
fmt.Println(entry)
}
从我的个人博客包中提取了代码,但在发布之前会先确认其运行情况。
我之前用插件在Markdown中撰写post_content,但当我查看wp_post时,发现它被奇怪的标签填满,像是一个魔窟。这让我决定趁此机会重新创建一个。也许尝试各种插件是个错误的选择。