本文基于 Golang 的爬虫框架 Go-Colly 进行数据抓取,然后存储到 MongoDB 数据库。根据搜索结果,相对来说最成熟的 MongoDB 驱动,应该是 mgo,但是目前 mgo 的作者已经停止维护。另外 MongoDB 官方也已经有对应 Golang 的驱动 mongo-go-driver,但是 Google 上相关的资料并不多。
1. Mgo 驱动
~~ 地址: https://godoc.org/labix.org/v2/mgo ~~
地址: https://github.com/globalsign/mgo
文档: https://godoc.org/github.com/globalsign/mgo
说明:上面第一个地址,是 mgo 的原地址,目前作者已经停止维护。第二个地址是基于原作者的社区维护版本,也是作者推荐的方案之一。
请参考相关项目中的使用:
本文以下内容请忽略,不建议使用。
2. 官方驱动
地址: https://github.com/mongodb/mongo-go-driver
文档:https://godoc.org/github.com/mongodb/mongo-go-driver/mongo
说明:遇到些问题,相关资料不是很多,尤其是缺少 Demo 可以参考。
3. 官方驱动简单测试
// blog.phpha.com
# service/client.go
package mongodb
import (
"context"
"fmt"
"github.com/mongodb/mongo-go-driver/mongo"
"github.com/mongodb/mongo-go-driver/mongo/findopt"
"log"
)
const (
MONGODB string = "mongodb://localhost:27017"
DATABASE string = "test"
)
func GetClient() *mongo.Client {
client, err := mongo.NewClient(MONGODB)
if err != nil {
log.Fatal(err)
}
err = client.Connect(context.TODO())
if err != nil {
log.Fatal(err)
}
return client
}
// 查询
func Find(client *mongo.Client, collection_name string, filter interface{}, opts ...*options.FindOptions) mongo.Cursor {
collection := client.Database(dbName).Collection(collection_name)
cur, err := collection.Find(context.Background(), filter, opts...)
if err != nil {
log.Fatal(err)
}
defer cur.Close(context.Background())
return cur
}
// 查询单条
func FindOne(client *mongo.Client, collection_name string, filter interface{}) *bson.Document {
collection := client.Database(dbName).Collection(collection_name)
result := bson.NewDocument()
err := collection.FindOne(context.Background(), filter).Decode(result)
if err != nil {
log.Fatal(err)
}
return result
}
// 计数
func Count(client *mongo.Client, collection_name string, filter interface{}) int64 {
collection := client.Database(dbName).Collection(collection_name)
res, err := collection.Count(context.Background(), filter)
if err != nil {
log.Fatal(err)
}
return res
}
// 插入
func Insert(client *mongo.Client, collection_name string, document interface{}) interface{} {
collection := client.Database(dbName).Collection(collection_name)
res, err := collection.InsertOne(context.Background(), document)
if err != nil {
// fmt.Print(err)
return ""
}
return res.InsertedID
}
// 更新
func Update(client *mongo.Client, collection_name string, filter interface{}, document interface{}, opts ...*options.FindOneAndUpdateOptions) bool {
collection := client.Database(dbName).Collection(collection_name)
res := collection.FindOneAndUpdate(context.Background(), filter, document, opts...)
if res.Decode(res) != nil {
return false
}
return true
}
// 删除
func Delete(client *mongo.Client, collection_name string, filter interface{}) int64 {
collection := client.Database(dbName).Collection(collection_name)
res, err := collection.DeleteOne(context.Background(), filter)
if err != nil {
log.Fatal(err)
}
return res.DeletedCount
}
// blog.phpha.com
目前遇到的问题就是,在查询时,不加任何条件,但是每次最多只能返回 101 条数据。
如果配合上 limit(N) ,当 N 大于 101 时,也依然无效。暂时未找到原因。
临时方案就是多次分页查询,比如我每次查询 100 条,多次查询。
// blog.phpha.com
// 数据库
client := mongodb.GetClient()
// 查询商圈
count := mongodb.Count(client, "bizcircle", map[string]interface{}{})
for i := 1; i <= int(math.Ceil(float64(count)/float64(100))); i++ {
cur := mongodb.Find(client, "bizcircle", map[string]interface{}{}, []findopt.Find{findopt.Skip(int64((i - 1) * 100)), findopt.Limit(100)})
// 循环遍历
for cur.Next(context.Background()) {
elem := bson.NewDocument()
err := cur.Decode(elem)
if err != nil {
log.Fatal(err)
}
// 当前商圈
bizcircleId := elem.LookupElement("bizcircle_id").Value().StringValue()
// 后续处理
}
}
// blog.phpha.com