如何encode/decodemongodb游标?

How to encode/decode mongodb cursor?

我需要建立一个 "pages" 的列表,所以其中的一部分会有一个 cursor. The issue is that I can't find a way to encode(to string) and decode the cursor. Any idea? The Cursor 接口没有 "encoding" 方法(有 ID,虽然没有记录)并且有无法从字符串(或整数)创建新游标。

type Cursor interface {

    // Get the ID of the cursor.
    ID() int64

    // Get the next result from the cursor.
    // Returns true if there were no errors and there is a next result.
    Next(context.Context) bool

    Decode(interface{}) error

    DecodeBytes() (bson.Reader, error)

    // Returns the error status of the cursor
    Err() error

    // Close the cursor.
    Close(context.Context) error
}

为什么我需要对光标进行编码?

通过 html 或 JSON API 为终端客户提供分页。

mongo.Cursor 对象不是您可以编码并存放起来供以后使用的东西,就像您打算使用它的目的一样。

A mongo.Cursor 是用来迭代 "live query" 文档流的东西。您不能将它用于return您发送给客户的一批文档,当客户请求更多文档(下一页)时,您解码存储的光标并从您离开的地方继续。游标在引擎盖下有一个服务器端资源,它会保留 10 分钟(可配置,请参阅 cursorTimeoutMillis)或直到您隐式关闭游标。如果客户需要更多文档,您不希望在等待客户时保持光标 "alive",尤其是在流量较大的应用程序中。您的 MongoDB 很快就会 运行 耗尽资源。如果游标因超时而关闭,则任何从游标读取的尝试都将导致错误 "Cursor not found, cursor id: #####"

Cursor.Decode() 方法不是从某种编码形式解码游标。就是把光标指定的下一个文档解码成Go值。

这就是为什么没有神奇的 mongo.NewCursor()mongo.ParseCursor()mongo.DecodeCursor() 功能。 mongo.Cursor 通过执行查询 交给 给你,例如Collection.Find():

func (coll *Collection) Find(ctx context.Context, filter interface{},
    opts ...findopt.Find) (Cursor, error)

MongoDB 不提供可序列化游标。 Cursor is not serializable. The recommended workaround 是使用范围查询并在通常随时间变化方向一致的字段上排序,例如 _id

function printStudents(startValue, nPerPage) {
  let endValue = null;
  db.students.find( { _id: { $lt: startValue } } )
             .sort( { _id: -1 } )
             .limit( nPerPage )
             .forEach( student => {
               print( student.name );
               endValue = student._id;
             } );

  return endValue;
}

有一个 go 包 minquery 试图使游标 query/serialization 更方便。您可能会发现它有帮助。