Пагинация драйвера MongoDB

В настоящее время я могу вернуть все свои продукты из коллекции. Однако я хочу иметь возможность возвращать продукты, которые идут после определенного идентификатора продукта (который будет последним на стороне клиента, чтобы они могли загружать больше)

Текущий способ (вернуть все)

query := bson.M{}

var product ReturnedProdcut
    var products []ReturnedProduct
    cur, err := mg.Db.Collection("products").Find(c.Request().Context(), query)
    if err != nil {
        fmt.Println(err)
    }
    for cur.Next(c.Request().Context()) {
        err := cur.Decode(&product)
        if err != nil {
            fmt.Println(err)
        }
        products = append(products, product)

    }

    // return products list in JSON format
    return c.JSON(http.StatusOK, products)

Попытка нового способа (возврат на основе страницы)

afterID := c.QueryParam("afterID")
if afterID == "" {
   // get from start of collection based on latest date
}
// get 10 products after this ID, if no ID then get from start

query := bson.M{}

var product ReturnedProduct
    var products []Returnedproduct
    //.find(afterId).limit(10) - something like this?
    
    cur, err := mg.Db.Collection("products").Find(c.Request().Context(), query)
    if err != nil {
        fmt.Println(err)
    }
    for cur.Next(c.Request().Context()) {
        err := cur.Decode(&product)
        if err != nil {
            fmt.Println(err)
        }
        products = append(products, product)

    }

    // return products list in JSON format
    return c.JSON(http.StatusOK, products)
Использование JavaScript и MongoDB
Использование JavaScript и MongoDB
Сегодня я собираюсь вкратце рассказать о прототипах в JavaScript, а также представить и объяснить вам работу с базой данных MongoDB.
1
0
627
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы можете построить запрос, в котором _id больше, чем afterID, и в этом случае вы также должны указать сортировку по _id. Для сортировки и установки лимита вы можете использовать options.FindOptions.

Вы также должны использовать Cursor.All() для декодирования всех результатов, а не по одному.

Вот как это может выглядеть:

query := bson.M{"_id": bson.M{"$gt": afterID}}
opts := options.Find().
    SetSort(bson.M{"_id": 1}).
    SetLimit(10)
    
ctx := c.Request().Context()

curs, err := mg.Db.Collection("products").Find(ctx, query, opts)
if err != nil {
    // Handle error
}

var products []Returnedproduct
if err = curs.All(ctx, &products); err != nil {
    // Handle error
}

return c.JSON(http.StatusOK, products)

Мои идентификаторы примитивны. ObjectID, поэтому я полагаю, их нельзя отсортировать по числовым?

Henry 15.12.2020 23:21

@Henry ObjectID упорядочены, их можно сортировать, что примерно эквивалентно временному порядку (с точностью до секунды).

icza 16.12.2020 01:24

Официальный драйвер MongoDB Go также имеет *FindOptions необязательный параметр, который вы также можете изучить.

 pageOptions := options.Find()
 pageOptions.SetSkip(int64(page)) //0-i
 pageOptions.SetLimit(int64(limit)) // number of records to return

 cur, err := userCollection.Find(c.Request().Context(), bson.D{{}}, pageOptions)
 if err != nil {
    // handle error
 }

 defer cur.Close(ctx)
 var products []Returnedproduct
 for cur.Next(c.Request().Context()) {
    var product Returnedproduct
    if err := cur.Decode(&product); err != nil {
        // handle error
    }
    products = append(products, &product)
 }

 if err := cur.Err(); err != nil {
    // handle error
 }

Другие вопросы по теме