使用 mongoose 和 nestjs 进行分页

Posted

技术标签:

【中文标题】使用 mongoose 和 nestjs 进行分页【英文标题】:Pagination with mongoose and nestjs 【发布时间】:2021-03-01 12:29:26 【问题描述】:

我正在尝试使用 mongoose paginate 对一组值进行分页。

class subNotes 
  @Prop()
  Note: string;
  @Prop()
  Date: Date;

@Schema()
class Travel extends Document 
  @Prop()
  Country: string;
  @Prop()
  Recommendation: string;
  @Prop()
  Level: number;
  @Prop()
  LevelDescr: string;
  @Prop()
  Date: Date;
  @Prop()
  Notes: [subNotes];

export const TravelSchema = SchemaFactory.createForClass(Travel); TravelSchema.plugin(mongoosePaginate); 所以 subnotes 每周更新一次,并且会有很多我想在 service sice 上分页的信息。 对于那个我在我的控制器中提供页面和限制之类的参数

async createSlugs(
    @Query('page') page = 1,
    @Query('limit') limit = 10,
    @Param('country') country: string,
  ) 
    limit = limit > 100 ? 100 : limit;
    return await this.travelService.getTravelInfo(
      
        limit: Number(limit),
        page: Number(page),
      ,
      country,
    );
  

在服务上,我将我的文档作为分页模型注入并尝试像这样实现服务:

 async getTravelInfo(page = 1, limit = 10, country: string) 
    await this.saveTravelInfo(country);

    const options = 
      page: Number(page),
      limit: Number(limit),
    ;

    return await this.notesModel.paginate( Country: country , options);
  

然而分页并没有做任何事情,整个国家数据都被选中了。有什么建议吗?

async getTravelInfo(page = 1, limit = 10, country: string) 
    await this.saveTravelInfo(country);

    const options = 
      populate: 'subNotes',
      page: Number(page),
      limit: Number(limit),
    ;
    console.log(options);

    return await this.notesModel.paginate( Country: country , options);
  

所以限制基本上是复制我的子注释中的内容。如果我设置限制 1,则返回所有内容,即 200 个文档。如果我输入限制 2,则返回 400 个文档。 :|

【问题讨论】:

【参考方案1】:

所以看看这个我做了这个包 使用 mongoose 在 Nestjs 中实现键集分页变得简单?

https://www.npmjs.com/package/nestjs-keyset-paginator

【讨论】:

【参考方案2】:

您可以使用mongoose-paginate-plugin 来实现此功能。

一个可能的起点;

import  Inject, Injectable  from '@nestjs/common';
import 
  Connection, Document, PaginateModel, Schema,
 from 'mongoose';
import  InjectConnection  from '@nestjs/mongoose';

import TravelSchema from './travel.schema';

interface IRunAnything extends Document
  [key: string]: any;


type SampleModel<T extends Document> = PaginateModel<T>;

@Injectable()
export default class ProfileRepository 
  constructor(
    @InjectConnection() private connection: Connection
  ) 

  /**
   * Run the query.
   * The query are just your filters.
   *
   * @param query
   * @param offset
   * @param limit
   */
  async getTravelInfo(query: object, offset = 10, limit = 10) 

    const dynamicModel: SampleModel<IRunAnything> = this.connection.model<IRunAnything>('Travel', this.schema) as SampleModel<IRunAnything>;

    const customLabels = 
      docs: 'nodes',
      page: 'currentPage',
      totalPages: 'pageCount',
      limit: 'perPage',
      totalDocs: 'itemCount',
    ;

    return dynamicModel.paginate(query,  customLabels, offset, limit );
  

该解决方案有点老套,但您可以在此基础上进行构建并适应您的用例。

记得将插件添加到您的架构中。

npm i mongoose-paginate-v2

...
import * as mongoosePaginate from 'mongoose-paginate-v2';

TravelSchema.plugin(mongoosePaginate)

...

【讨论】:

以上是关于使用 mongoose 和 nestjs 进行分页的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Jest 和 NestJS 模拟 Mongoose 的“lean()”查询?

在 @nestjs/mongoose 中设置 mongoose 全局选项

NestJS 和 Mongoose 使用 Mongoose-Sequence

如何在 NestJs 和 typescript 中使用 `mongoose-delete` 插件?

使用 nestjs 和 mongoose 哈希密码在生产中崩溃

nestjs : 定义要在 mongoose 和 graphql 中使用的地图/数组