search n count, offset
This commit is contained in:
@@ -1 +1,7 @@
|
||||
export class CreatePostDto {}
|
||||
import {IsNotEmpty, IsString} from "class-validator";
|
||||
|
||||
export class CreatePostDto {
|
||||
@IsString({ each: true })
|
||||
@IsNotEmpty()
|
||||
paragraphs: string[];
|
||||
}
|
||||
|
||||
@@ -13,6 +13,9 @@ class Post {
|
||||
@Column()
|
||||
public content: string;
|
||||
|
||||
@Column('text', { array: true })
|
||||
public paragraphs: string[];
|
||||
|
||||
@Column({nullable: true})
|
||||
public category?: string;
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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) {
|
||||
@@ -39,10 +39,34 @@ export class PostsService {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
getAllPosts() {
|
||||
return this.repo.find({relations: ['author']});
|
||||
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) {
|
||||
|
||||
@@ -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,
|
||||
|
||||
5
src/posts/types/postCountBody.interface.ts
Normal file
5
src/posts/types/postCountBody.interface.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
interface PostCountResult {
|
||||
count: number;
|
||||
}
|
||||
|
||||
export default PostCountResult;
|
||||
23
src/utils/types/paginationParams.ts
Normal file
23
src/utils/types/paginationParams.ts
Normal 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;
|
||||
}
|
||||
Reference in New Issue
Block a user