-1

我需要建立一个“页面”列表,所以其中一部分会有一个cursor。问题是我找不到编码(到字符串)和解码光标的方法。任何想法?Cursor接口没有“编码”方法(有 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 向最终客户端提供分页。

4

2 回答 2

1

MongoDB 不提供可序列化的游标。光标不可序列化。推荐的解决方法是使用范围查询并对通常随时间以一致方向更改的字段进行排序,例如_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 package minquery试图使游标查询/序列化更方便。您可能会发现它很有帮助。

于 2018-07-04T12:43:11.447 回答
0

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

Amongo.Cursor是您用来迭代“实时查询”(文档流)的东西。您不能使用它来返回您发送给客户的一批文档,并且当客户请求更多文档(下一页)时,您解码存储的光标并继续您离开的地方。游标在后台有一个服务器端资源,它会保留 10 分钟(可配置,请参阅cursorTimeoutMillis)或直到您隐式关闭游标。如果客户需要更多文档,尤其是在流量较大的应用程序中,您不希望在等待客户时保持光标“活动”。您的 MongoDB 将很快耗尽资源。如果游标因超时而关闭,任何从游标读取的尝试都将导致错误“未找到游标,游标 ID:

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

这就是为什么没有魔法mongo.NewCursor()mongo.ParseCursor()功能mongo.DecodeCursor()。Amongo.Cursor通过执行查询传递Collection.Find()给您,例如:

func (coll *Collection) Find(ctx context.Context, filter interface{},
    opts ...findopt.Find) (Cursor, error)
于 2018-07-03T14:18:05.363 回答