使用mongoose和nestjs分页

bqujaahr  于 2023-06-30  发布在  Go
关注(0)|答案(3)|浏览(145)

我试图使用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); mysql. println(mysql);因此,subnotes是每周更新,将有很多信息,我想分页的服务sice。为此,我在控制器中提供了apage和limit之类的参数

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);
  }

所以limit基本上就是复制我的子音符里面的内容。如果我输入Limit 1,则返回所有内容,即200个文档。如果输入Limit 2,则返回400个文档。:|

rbl8hiat

rbl8hiat1#

所以看看这个,我做了这个包,使键集分页的实现在nestjs与mongoose简单🙂
https://www.npmjs.com/package/nestjs-keyset-paginator

i7uaboj4

i7uaboj42#

您可以使用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)

...
zaqlnxep

zaqlnxep3#

以下是在Nest JS中使用mongoose-paginate-v2的步骤...
在这里,我以Category模块为例……

  • 创建文件category.module.ts
import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';

import { CmsAuthModule } from './cms-auth.module';
import { CmsAuthService } from '../../service/cms-auth.service';
import { CategoryService } from 'src/service/category.service';
import { CategoryController } from 'src/controllers/cms/category.controller';
import { Category, CategorySchema } from 'src/entities/category.entity';

@Module({
  imports: [
    MongooseModule.forFeature([
      { name: Category.name, schema: CategorySchema },
    ]),
    CmsAuthModule,
  ],
  controllers: [CategoryController],
  providers: [CategoryService, CmsAuthService],
})
export class CategoryModule {
  // constructor() {
  //   mongoose.plugin(mongoosePaginate);
  // }
}

在中使用import { PaginateModel } from 'mongoose',而不是在category.service.ts中使用import { Model } from 'mongoose'

import { ConflictException, Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { StatusCodes } from 'http-status-codes';
import { PaginateModel } from 'mongoose';
import { CATEGORY_CONFIG } from 'src/config/constants';
import { MESSAGE } from 'src/config/message';
import { CreateCategoryDto, UpdateCategoryDto } from 'src/dtos/category.dto';
import { Category, CategoryDocument } from 'src/entities/category.entity';

@Injectable()
export class CategoryService {
  constructor(
    @InjectModel(Category.name)
    private categoryModal: PaginateModel<CategoryDocument>,
  ) {}

  async findAll() {
    const query = {
      status: CATEGORY_CONFIG.STATUS_TYPE.ACTIVE,
    };
    const options = {
      select: ['name'],
    };
    const resData = await this.categoryModal.paginate(query, options);
    
    return {
      statusCode: StatusCodes.OK,
      message: MESSAGE.SUCCESS.CATEGORY_FETCH_SUCCESS,
      data: resData,
    };
  }
}

下面是相同的实体文件...在这个文件中使用CategorySchema.plugin(mongoosePaginate);,这样它将给予mongoosePaginate中可用的功能。

import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { HydratedDocument } from 'mongoose';
import * as mongoosePaginate from 'mongoose-paginate-v2';

export type CategoryDocument = HydratedDocument<Category>;

@Schema({ timestamps: true })
export class Category {
  @Prop({ required: true, type: String })
  name: string;

  @Prop({ required: true, type: String })
  status: string;
}

export const CategorySchema = SchemaFactory.createForClass(Category);

CategorySchema.plugin(mongoosePaginate);

相关问题