Пагинация результатов поиска на основе курсора

Не могли бы вы просмотреть мою функцию разбивки на страницы в поиске GraphQL? Боюсь, могут быть проблемы с производительностью или что-то в этом роде. Особенно в разделе агрегации и в этом const result: any = await this.BooksModel.findOne( раздел.

Я использую MongoDB в качестве базы данных и строку ISO Date в качестве курсора.

Я попытался найти в Интернете какой-либо пример разбивки на страницы, но не нашел.

async getBooks({
    first,
    after,
    last,
    before,
    search,
}: {
    first?: number | null
    after?: string | null
    last?: number | null
    before?: string | null
    search?: string | null
}) {
    if (first && last)
        throw new AppError(
            '`first` and `last` cannot be used at the same time',
            400,
        )
    if (!first && !last)
        throw new AppError('Either `first` or `last` is required', 400)
    if (after && before)
        throw new AppError(
            '`after` and `before` cannot be used at the same time',
            400,
        )
    if (search && last)
        throw new AppError('`search` and `last` is not allowed', 400)

    if (search) {
        let score = null
        if (after) {
            const date = new Date(after)
            const result: any = await this.BooksModel.findOne(
                {
                    created: date,
                    $text: { $search: search },
                },
                { score: { $meta: 'textScore' } },
            )
            score = result._doc.score
        }

        const filter = { score: { $lt: score } }
        const limit = first ? first : last!

        const books = await this.BooksModel.aggregate([
            { $match: { $text: { $search: search } } },
            { $addFields: { score: { $meta: 'textScore' }, id: '$_id' } },
            ...(score ? [{ $match: filter }] : []),
            { $sort: { score: { $meta: 'textScore' } } },
            { $limit: limit },
        ])

        return books
    } else {
        const sort = { created: first ? -1 : 1 }
        const limit = first ? first : last!

        const books = await this.BooksModel.find({
            ...(after ? { created: { $lt: new Date(after) } } : null),
            ...(before ? { created: { $gt: new Date(before) } } : null),
        })
            .sort(sort)
            .limit(limit)
            .exec()

        return books
    }
}
```

0

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *