search n count, offset

This commit is contained in:
Phuoc Nguyen
2025-05-23 11:03:38 +07:00
parent 17ba8b1c7d
commit 4c51aad94e
7 changed files with 90 additions and 8 deletions

View File

@@ -1 +1,7 @@
export class CreatePostDto {}
import {IsNotEmpty, IsString} from "class-validator";
export class CreatePostDto {
@IsString({ each: true })
@IsNotEmpty()
paragraphs: string[];
}

View File

@@ -13,6 +13,9 @@ class Post {
@Column()
public content: string;
@Column('text', { array: true })
public paragraphs: string[];
@Column({nullable: true})
public category?: string;

View File

@@ -16,6 +16,7 @@ import {CreatePostDto} from './dto/create-post.dto';
import {UpdatePostDto} from './dto/update-post.dto';
import JwtAuthenticationGuard from "../authentication/jwt-authentication.guard";
import RequestWithUser from "../authentication/requestWithUser.interface";
import {PaginationParams} from "../utils/types/paginationParams";
@Controller('posts')
@UseInterceptors(ClassSerializerInterceptor)
@@ -31,11 +32,14 @@ export class PostsController {
@Get()
async getPosts(@Query('search') search: string) {
async getPosts(
@Query('search') search: string,
@Query() { offset, limit }: PaginationParams
) {
if (search) {
return this.postsService.searchForPosts(search);
return this.postsService.searchForPosts(search, offset, limit);
}
return this.postsService.getAllPosts();
return this.postsService.getAllPosts(offset, limit);
}
@Get()

View File

@@ -3,7 +3,7 @@ import {CreatePostDto} from './dto/create-post.dto';
import {UpdatePostDto} from './dto/update-post.dto';
import User from "../users/entities/user.entity";
import {InjectRepository} from "@nestjs/typeorm";
import {Repository} from "typeorm";
import {FindManyOptions, MoreThan, Repository} from "typeorm";
import Post from './entities/post.entity';
import {PostNotFoundException} from "./exception/postNotFound.exception";
import PostsSearchService from "./postsSearch.service";
@@ -27,7 +27,7 @@ export class PostsService {
return newPost;
}
async searchForPosts(text: string) {
async searchForPosts(text: string, offset?: number, limit?: number) {
const results = await this.postsSearchService.search(text);
const ids = results.flatMap(result => result.hits.hits.map(hit => hit._source.id));
if (!ids.length) {
@@ -41,8 +41,32 @@ export class PostsService {
getAllPosts() {
return this.repo.find({relations: ['author']});
async getAllPosts(offset?: number, limit?: number, startId = 0) {
const where: FindManyOptions<Post>['where'] = {};
let separateCount = 0;
if (startId) {
where.id = MoreThan(startId);
separateCount = await this.repo.count();
}
const [items, count] = await this.repo.findAndCount({
where,
relations: {
author: true
},
order: {
id: 'ASC'
},
skip: offset,
take: limit
});
return {
items,
count: startId ? separateCount : count
}
}
async getPostById(id: number) {

View File

@@ -3,6 +3,7 @@ import {ElasticsearchService} from '@nestjs/elasticsearch';
import Post from "./entities/post.entity";
import {PostSearchResult} from "./types/postSearchResult.interface";
import {PostSearchBody} from "./types/postSearchBody.interface";
import PostCountResult from "./types/postCountBody.interface";
@Injectable()
export default class PostsSearchService {
@@ -25,6 +26,22 @@ export default class PostsSearchService {
});
}
async count(query: string, fields: string[]) {
const result = await this.elasticsearchService.count({
index: this.index,
query: {
multi_match: {
query,
fields,
},
},
});
return result.count;
}
async search(text: string) {
const result = await this.elasticsearchService.search<PostSearchResult>({
index: this.index,

View File

@@ -0,0 +1,5 @@
interface PostCountResult {
count: number;
}
export default PostCountResult;

View File

@@ -0,0 +1,23 @@
import { IsNumber, Min, IsOptional } from 'class-validator';
import { Type } from 'class-transformer';
export class PaginationParams {
@IsOptional()
@Type(() => Number)
@IsNumber()
@Min(1)
startId?: number;
@IsOptional()
@Type(() => Number)
@IsNumber()
@Min(0)
offset?: number;
@IsOptional()
@Type(() => Number)
@IsNumber()
@Min(1)
limit?: number;
}