Skip to content

Commit

Permalink
feat(exercises): ⚡ added search query on exercises endpoint
Browse files Browse the repository at this point in the history
added feature for getting the exercise based on bodypart, exercise name, muscles name, equipment
  • Loading branch information
cyberboyanmol committed Aug 24, 2024
1 parent 2016e16 commit e639f2c
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 18 deletions.
20 changes: 11 additions & 9 deletions src/infra/mongodb/models/exercises/exercise.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,26 +30,22 @@ const exerciseSchema = new mongoose.Schema<IExerciseDoc, IExerciseModel>(
],
targetMuscles: [
{
type: String,
index: true
type: String
}
],
bodyParts: [
{
type: String,
index: true
type: String
}
],
equipments: [
{
type: String,
index: true
type: String
}
],
secondaryMuscles: [
{
type: String,
index: true
type: String
}
]
},
Expand All @@ -59,7 +55,13 @@ const exerciseSchema = new mongoose.Schema<IExerciseDoc, IExerciseModel>(
)

exerciseSchema.plugin(toJSONWithoutId)

exerciseSchema.index({
name: 'text',
targetMuscles: 'text',
bodyParts: 'text',
equipments: 'text',
secondaryMuscles: 'text'
})
/**
* check if the similar equipment name already exists
* @param {string} name
Expand Down
24 changes: 17 additions & 7 deletions src/modules/exercises/controllers/exercise.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,19 +152,29 @@ export class ExerciseController implements Routes {
tags: ['Exercises'],
summary: 'Retrive all exercises.',
description: 'Retrive list of all the exercises.',
operationId: 'getMuscles',
operationId: 'getExercises',
request: {
query: z.object({
search: z.string().optional().openapi({
title: 'Search Query',
description:
'A string to filter exercises based on a search term. This can be used to find specific exercises by name or description.',
type: 'string',
example: 'cardio',
default: ''
}),
offset: z.coerce.number().nonnegative().optional().openapi({
title: '',
description: 'Number of exercises to skip',
title: 'Offset',
description:
'The number of exercises to skip from the start of the list. Useful for pagination to fetch subsequent pages of results.',
type: 'number',
example: 10,
default: 0
}),
limit: z.coerce.number().positive().max(100).optional().openapi({
title: '',
description: 'Maximum number of exercises to return',
title: 'Limit',
description:
'The maximum number of exercises to return in the response. Limits the number of results for pagination purposes.',
maximum: 100,
minimum: 1,
type: 'number',
Expand Down Expand Up @@ -197,9 +207,9 @@ export class ExerciseController implements Routes {
}
}),
async (ctx) => {
const { offset, limit = 10 } = ctx.req.valid('query')
const { offset, limit = 10, search } = ctx.req.valid('query')
const { origin, pathname } = new URL(ctx.req.url)
const response = await this.exerciseService.getExercise({ offset, limit })
const response = await this.exerciseService.getExercise({ offset, limit, search })
return ctx.json({
success: true,
data: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { IExerciseDoc, IExerciseModel } from '#infra/mongodb/models/exercises/ex
export interface GetExerciseArgs {
offset?: number
limit?: number
search?: string
}

export interface GetExerciseReturnArgs {
Expand All @@ -15,14 +16,16 @@ export interface GetExerciseReturnArgs {
export class GetExercisesUseCase implements IUseCase<GetExerciseArgs, GetExerciseReturnArgs> {
constructor(private readonly exerciseModel: IExerciseModel) {}

async execute({ offset, limit }: GetExerciseArgs): Promise<GetExerciseReturnArgs> {
async execute({ offset, limit, search }: GetExerciseArgs): Promise<GetExerciseReturnArgs> {
try {
const safeOffset = Math.max(0, Number(offset) || 0)
const safeLimit = Math.max(1, Math.min(100, Number(limit) || 10))
const searchQuery = search ? { $text: { $search: search } } : {}

const totalCounts = await this.exerciseModel.countDocuments()
const totalPages = Math.ceil(totalCounts / safeLimit)
const currentPage = Math.floor(safeOffset / safeLimit) + 1
const result = await this.exerciseModel.find({}).skip(safeOffset).limit(safeLimit).exec()
const result = await this.exerciseModel.find(searchQuery).skip(safeOffset).limit(safeLimit).exec()

return {
totalPages,
Expand Down

0 comments on commit e639f2c

Please sign in to comment.