doufeng3602
2018-07-03 11:55
浏览 42

如何编码/解码mongodb游标?

I need to build a list of "pages" so part of this there will be a cursor. The issue is that I can't find a way to encode(to string) and decode the cursor. Any idea? The Cursor interface has no "encoding" method(there is ID, though undocumented) and there is no way to create a new cursor from a string(or 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
}

Why do I need the cursor encoded?

To provide pagination to the end client through a html or JSON API.

图片转代码服务由CSDN问答提供 功能建议

我需要构建“页面”列表,因此其中一部分将是光标。 问题是我找不到编码(对字符串)和解码光标的方法。 任何想法? Cursor 接口没有“编码”方法(

  type Cursor interface {
 
 //获取,但没有ID,尽管未记录),并且无法从字符串(或int)创建新的游标。  
 ID()int64 
 
 //从光标获取下一个结果。
 //如果没有错误并且有下一个结果,则返回true。
 Next(上下文。 上下文)bool 
 
 Decode(interface {})错误
 
 DecodeBytes()(bson.Reader,错误)
 
 //返回光标的错误状态
 Err()错误
 \  n //关闭游标。
关闭(context.Context)错误
} 
   
 
 

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

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

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

2条回答 默认 最新

  • dow58115 2018-07-04 12:43
    已采纳

    MongoDB does not provide a serializable cursor. Cursor is not serializable. The recommended workaround is to use a range query and sort on a field that generally changes in a consistent direction over time such _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;
    }
    

    There is a go package minquery that tries to make the cursor query/serialization more convenient. You may find it helpful.

    点赞 打赏 评论
  • duanbin198788 2018-07-03 14:18

    A mongo.Cursor object isn't something you can encode and put away for later use, like what you intend to use it for.

    A mongo.Cursor is something you use to iterate over a "live query", a stream of documents. You can't use it to return a batch of documents which you send to your client, and when the client requests more documents (the next page), you decode the stored cursor and continue where you left off. A cursor have a server side resource under the hood, which is kept for 10 minutes (configurable, see cursorTimeoutMillis) or until you close the cursor implicitly. You do not want to keep the cursor "alive" while waiting for the client if he / she needs more documents, especially in an application with large traffic. Your MongoDB would quickly run out of resources. If cursor is closed by timeout, any attempt to read from the cursor will result with error "Cursor not found, cursor id: #####"

    The Cursor.Decode() method is not to decode a cursor from some encoded form. It is to decode the next document the cursor designates into a Go value.

    That's why there is no magic mongo.NewCursor() or mongo.ParseCursor() or mongo.DecodeCursor() function. A mongo.Cursor is handed to you by executing queries, e.g. with Collection.Find():

    func (coll *Collection) Find(ctx context.Context, filter interface{},
        opts ...findopt.Find) (Cursor, error)
    
    点赞 打赏 评论

相关推荐 更多相似问题