如何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 更方便。您可能会发现它有帮助。
我需要建立一个 "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 更方便。您可能会发现它有帮助。