Как кодировать / декодировать курсор Mongodb? - PullRequest
0 голосов
/ 03 июля 2018

Мне нужно создать список «страниц», поэтому частью этого будет курсор . Проблема в том, что я не могу найти способ кодировать (в строку) и декодировать курсор. Любая идея? Интерфейс Cursor не имеет метода «кодирования» (есть идентификатор, хотя и недокументированный), и нет способа создать новый курсор из строки (или 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 голосов
/ 04 июля 2018

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 minquery , который пытается сделать запрос / сериализацию курсора более удобными. Вы можете найти это полезным.

0 голосов
/ 03 июля 2018

A mongo.Cursor объект - это не то, что вы можете закодировать и убрать для дальнейшего использования, например, для чего вы собираетесь его использовать.

A mongo.Cursor - это то, что вы используете для итерации по «живому запросу», потоку документов. Вы не можете использовать его для возврата пакета документов, который вы отправляете своему клиенту, и когда клиент запрашивает больше документов (следующая страница), вы декодируете сохраненный курсор и продолжаете с того места, где остановились. У курсора есть серверный ресурс под капотом, который сохраняется в течение 10 минут (настраивается, см. cursorTimeoutMillis ) или до тех пор, пока вы не закроете курсор неявно. Вы не хотите, чтобы курсор оставался «живым» во время ожидания клиента, если ему нужно больше документов, особенно в приложении с большим трафиком. Ваш MongoDB быстро исчерпает ресурсы. Если курсор закрыт по тайм-ауту, любая попытка чтения с курсора приведет к ошибке «Курсор не найден, идентификатор курсора: #####»

Метод 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)
...