登录
首页 >  Golang >  Go问答

(CursorNotFound)在命名空间"dbName.collection"中无法找到游标,ID为885805460243113719

来源:stackoverflow

时间:2024-03-01 22:09:25 322浏览 收藏

你在学习Golang相关的知识吗?本文《(CursorNotFound)在命名空间"dbName.collection"中无法找到游标,ID为885805460243113719》,主要介绍的内容就涉及到,如果你想提升自己的开发能力,就不要错过这篇文章,大家要知道编程理论基础和实战操作都是不可或缺的哦!

问题内容

以下是从数据库中获取结果的代码,提供集合、过滤查询、排序查询和限制数量。

func DBFetch(collection *mongo.Collection, filter interface{}, sort interface{}, limit int64) ([]bson.M, error) {
    findOptions := options.Find()
    findOptions.SetLimit(limit)
    findOptions.SetSort(sort)
    cursor, err := collection.Find(context.Background(), filter, findOptions)
    var result []bson.M
    if err != nil {
        logger.Client().Error(err.Error())
        sentry.CaptureException(err)
        cursor.Close(context.Background())
        return nil, err
    }
    if err = cursor.All(context.Background(), &result); err != nil {
        logger.Client().Error(err.Error())
        sentry.CaptureMessage(err.Error())
        return nil, err
    }
    return result, nil
}
  1. 我使用的是 mongo-go 驱动程序版本 1.8.2
  2. mongodb 社区版本 4.4.7 分片 mongo,有 2 个分片
  3. k8 中每个分片有 30 个 cpu,245gb 内存,有 1 个副本
  4. api 为 200 rpm
  5. api 从 mongo 获取数据并对其进行格式化并提供服务
  6. 我们在小学阶段就读和写。
  7. 大约每小时都会发生大量写入。
  8. 以毫秒为单位获取超时(大约 10ms-20ms)

正确答案


正如评论中@R2D2所指出的,当超过默认超时(10分钟)并且go没有请求下一组数据时,不会出现游标超时错误。

您可以采取多种解决方法来缓解此错误。

第一个选项是使用以下选项设置查找查询的批量大小。通过执行 do,您将指示 mongodb 以指定的块发送数据,而不是发送更多数据。请注意,这通常会增加 mongodb 和 go 服务器之间的往返时间。

findoptions := options.find()
findoptions.setbatchsize(10)  // <- batch size is set to `10`

cursor, err := collection.find(context.background(), filter, findoptions)

此外,您可以设置 nocursortimeout 选项,这将使您的 mongodb 查找查询结果游标指针保持活动状态,除非您手动关闭它。此选项是一把双刃剑,因为一旦不再需要该光标,您就必须手动关闭该光标,否则该光标将在内存中保留很长时间。

findoptions := options.find()
findoptions.setnocursortimeout(true)  // <- applies no cursor timeout option

cursor, err := collection.find(context.background(), filter, findoptions)

// very important
_ = cursor.close(context.background())  // <- don't forget to close the cursor

结合以上两个选项,下面将是您的完整代码。

func DBFetch(collection *mongo.Collection, filter interface{}, sort interface{}, limit int64) ([]bson.M, error) {
    findOptions := options.Find()
    findOptions.SetLimit(limit)
    findOptions.SetSort(sort)
    findOptions.SetBatchSize(10)  // <- Batch size is set to `10`
    findOptions.SetNoCursorTimeout(true)  // <- Applies no cursor timeout option
    cursor, err := collection.Find(context.Background(), filter, findOptions)
    var result []bson.M
    if err != nil {
        //logger.Client().Error(err.Error())
        //sentry.CaptureException(err)
        _ = cursor.Close(context.Background())
        return nil, err
    }
    if err = cursor.All(context.Background(), &result); err != nil {
        //logger.Client().Error(err.Error())
        //sentry.CaptureMessage(err.Error())
        return nil, err
    }
    // VERY IMPORTANT
    _ = cursor.Close(context.Background())  // <- Don't forget to close the cursor
    return result, nil
}

好了,本文到此结束,带大家了解了《(CursorNotFound)在命名空间"dbName.collection"中无法找到游标,ID为885805460243113719》,希望本文对你有所帮助!关注golang学习网公众号,给大家分享更多Golang知识!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>