我收集了2,000,000条记录
> db.events.count(); │
2000000
我使用golang mongodb客户端连接到数据库package main
import (
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
client, err := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://localhost:27888").SetAuth(options.Credential{
Username: "mongoadmin",
Password: "secret",
}))
if err != nil {
panic(err)
}
defer func() {
if err = client.Disconnect(ctx); err != nil {
panic(err)
}
}()
collection := client.Database("test").Collection("events")
var bs int32 = 10000
var b = true
cur, err := collection.Find(context.Background(), bson.D{}, &options.FindOptions{
BatchSize: &bs, NoCursorTimeout: &b})
if err != nil {
log.Fatal(err)
}
defer cur.Close(ctx)
s, n := runningtime("retrive db from mongo and publish to kafka")
count := 0
for cur.Next(ctx) {
var result bson.M
err := cur.Decode(&result)
if err != nil {
log.Fatal(err)
}
bytes, err := json.Marshal(result)
if err != nil {
log.Fatal(err)
}
count++
msg := &sarama.ProducerMessage{
Topic: "hello",
// Key: sarama.StringEncoder("aKey"),
Value: sarama.ByteEncoder(bytes),
}
asyncProducer.Input() <- msg
}
但是该程序仅检索约600,000条记录,而不是每次运行该程序时检索2,000,000条记录。$ go run main.go
done
count = 605426
nErrors = 0
2020/09/18 11:23:43 End: retrive db from mongo and publish to kafka took 10.080603336s
不知道为什么我想检索所有2,000,000条记录。谢谢你的帮助。 最佳答案
由于使用相同的ctx
上下文来迭代具有10秒超时的结果,因此获取结果的循环可能会提前结束。
这意味着,如果检索和处理200万条记录(包括连接)花费的时间超过10秒,则上下文将被取消,因此光标还将报告错误。
请注意,将 FindOptions.NoCursorTimeout
设置为true
只是为了防止光标因不 Activity 而超时,它不会覆盖使用的上下文的超时。
使用另一种上下文来执行查询并遍历结果,该上下文没有超时,例如 context.Background()
。
另请注意,要为find
构造选项,请使用helper方法,因此它看起来像这样简单而优雅:
options.Find().SetBatchSize(10000).SetNoCursorTimeout(true)
所以工作代码:ctx2 := context.Background()
cur, err := collection.Find(ctx2, bson.D{},
options.Find().SetBatchSize(10000).SetNoCursorTimeout(true))
// ...
for cur.Next(ctx2) {
// ...
}
// Also check error after the loop:
if err := cur.Err(); err != nil {
log.Printf("Iterating over results failed: %v", err)
}
关于mongodb - Mongodb不会使用游标检索具有200万条记录的集合中的所有文档,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/63950411/