如何编码/解码mongodb游标?

时间:2018-07-03 11:55:36

标签: mongodb go mongo-go

我需要建立一个“页面”列表,因此其中一部分将是cursor。问题是我找不到编码(对字符串)和解码光标的方法。任何想法? Cursor接口没有“ encoding”方法(虽然没有记录,但有ID),并且无法从字符串(或int)创建新的游标。

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向最终客户端提供分页。

2 个答案:

答案 0 :(得分:0)

mongo.Cursor对象不是您可以编码并存放起来供以后使用的对象,例如您打算使用的对象。

mongo.Cursor是您用来迭代“实时查询”(文档流)的东西。您不能使用它返回发送给客户端的一批文档,并且当客户端请求更多文档时(下一页),您将解码存储的游标并从上次中断的地方继续。游标具有服务器端资源,可以保留10分钟(可配置,请参见cursorTimeoutMillis),或者直到您隐式关闭游标为止。如果客户需要更多文档,尤其是在流量很大的应用程序中,则不希望在等待客户端时让光标保持“活动状态”。您的MongoDB将很快耗尽资源。如果游标因超时而关闭,则任何尝试从游标读取的操作都将产生错误“未找到游标,游标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)

答案 1 :(得分:0)

MongoDB不提供可序列化的游标。 Cursor无法序列化。 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,它试图使游标查询/序列化更加方便。您可能会发现它很有帮助。