Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: fixed get all users and populate option #24

Merged
merged 1 commit into from Oct 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
37 changes: 27 additions & 10 deletions src/core/abstracts/generic-repository.abstract.ts
@@ -1,18 +1,35 @@
import { ClientSession, FilterQuery, UpdateQuery } from 'mongoose'
import { ClientSession, FilterQuery, UpdateQuery } from 'mongoose';

export abstract class IGenericRepository<T> {

abstract find(fields: FilterQuery<T>, options?: { select?: string, isLean?: boolean })
abstract find(
fields: FilterQuery<T>,
options?: {
select?: string;
isLean?: boolean;
populate?: string | string[];
},
);

abstract findAllWithPagination(query: any, options?: { fields?: FilterQuery<T>, populate?: string | string[] })
abstract findAllWithPagination(
query: any,
options?: { fields?: FilterQuery<T>; populate?: string | string[] },
);

abstract findOne(key: FilterQuery<T>, session?: ClientSession, options?: { select?: string | string[], populate?: string | string[] })
abstract findOne(
key: FilterQuery<T>,
session?: ClientSession,
options?: { select?: string | string[]; populate?: string | string[] },
);

abstract create(payload: T | T[], session?: ClientSession)
abstract create(payload: T | T[], session?: ClientSession);

abstract update(key: FilterQuery<T>, payload: UpdateQuery<T>, session?: ClientSession)
abstract update(
key: FilterQuery<T>,
payload: UpdateQuery<T>,
session?: ClientSession,
);

abstract delete(key: FilterQuery<T>, session?: ClientSession)
abstract delete(key: FilterQuery<T>, session?: ClientSession);

abstract search(options: Record<string, any>, populate: string | string[])
}
abstract search(options: Record<string, any>, populate: string | string[]);
}
89 changes: 66 additions & 23 deletions src/frameworks/data-services/mongo/mongo-generic-repository.ts
Expand Up @@ -14,36 +14,63 @@ export class MongoGenericRepository<T> implements IGenericRepository<T> {
async create(payload: T | T[], session?: ClientSession) {
try {
if (Array.isArray(payload)) {
const data = session ? this._repository.insertMany(payload, { session }) : this._repository.insertMany(payload);
const data = session
? this._repository.insertMany(payload, { session })
: this._repository.insertMany(payload);
return Promise.resolve(data as any);
}
const instance = new this._repository(payload);
const data = session ? await instance.save({ session }) : await instance.save();
const data = session
? await instance.save({ session })
: await instance.save();
return Promise.resolve(data as any);
} catch (e) {
return Promise.reject(e);
}
}

async update(key: FilterQuery<T>, payload: UpdateQuery<T>, session?: ClientSession) {
async update(
key: FilterQuery<T>,
payload: UpdateQuery<T>,
session?: ClientSession,
) {
try {
const result = await this._repository.findOneAndUpdate({ ...key }, { ...payload }, { new: true }).session(session || null);
const result = await this._repository
.findOneAndUpdate({ ...key }, { ...payload }, { new: true })
.session(session || null);
return Promise.resolve(result);
} catch (e) {
return Promise.reject(e);
}
}

async find(fields: FilterQuery<T>, options?: { select?: string, isLean?: boolean }) {
async find(
fields: FilterQuery<T>,
options?: {
select?: string;
isLean?: boolean;
populate?: string | string[];
},
) {
try {
const data = options?.isLean ? await this._repository.find(fields).populate(this._populateOnFind).select(options?.select).lean() : await this._repository.find(fields).select(options?.select)
const data = options?.isLean
? await this._repository
.find(fields)
.populate(options?.populate)
.select(options?.select)
.lean()
: await this._repository.find(fields).select(options?.select);
return Promise.resolve(data);
} catch (e) {
return Promise.reject(e);
}
}

async findOne(key: FilterQuery<T>, session?: ClientSession, options?: { select?: string | string[], populate?: string | string[] }) {
async findOne(
key: FilterQuery<T>,
session?: ClientSession,
options?: { select?: string | string[]; populate?: string | string[] },
) {
try {
const result = await this._repository
.findOne(key)
Expand All @@ -55,7 +82,10 @@ export class MongoGenericRepository<T> implements IGenericRepository<T> {
return Promise.reject(e);
}
}
async findAllWithPagination(query: any, options?: { fields?: FilterQuery<T>, populate?: string | string[] }) {
async findAllWithPagination(
query: any,
options?: { fields?: FilterQuery<T>; populate?: string | string[] },
) {
try {
const perpage = Number(query.perpage) || 10;
const page = Number(query.page) || 1;
Expand All @@ -72,23 +102,31 @@ export class MongoGenericRepository<T> implements IGenericRepository<T> {
myDateFrom = convertDate(dateFrom);
myDateTo = convertDate(dateTo);

const queryObj: any = { ...query, ...options?.fields }
const excludedFields = ['page', 'perpage', 'dateFrom', 'dateTo', 'search', 'sortBy', 'orderBy'];
const queryObj: any = { ...query, ...options?.fields };
const excludedFields = [
'page',
'perpage',
'dateFrom',
'dateTo',
'search',
'sortBy',
'orderBy',
];
excludedFields.forEach((el) => delete queryObj[el]);

for (const key of Object.keys(queryObj)) {
if (key == 'createdAt') {
andArr.push({ [key]: { $gte: myDateFrom, $lt: myDateTo } });
} else {
andArr.push({
[key]: String(queryObj[key])
[key]: String(queryObj[key]),
});
// andArr.push({ [key]: queryObj[key] })
}
}
// https://stackoverflow.com/questions/35832113/and-expression-must-be-a-nonempty-array
const searchQuery = {
$and: andArr
$and: andArr,
};

const filterQuery = isEmpty(andArr) ? {} : searchQuery;
Expand All @@ -110,35 +148,40 @@ export class MongoGenericRepository<T> implements IGenericRepository<T> {
currentPage: Number(page),
total: total,
pageSize: perpage,
lastPage: Math.ceil(total / perpage)
}
lastPage: Math.ceil(total / perpage),
},
});
} catch (e) {
return Promise.reject(e);
}
}
async delete(key: FilterQuery<T>, session?: ClientSession) {
try {
const result = await this._repository.findOneAndDelete({ ...key }).session(session || null);
const result = await this._repository
.findOneAndDelete({ ...key })
.session(session || null);
return Promise.resolve(result);
} catch (e) {
return Promise.reject(e);
}
}

async search(options: { query: Record<string, any>, populate?: string | string[] }) {
async search(options: {
query: Record<string, any>;
populate?: string | string[];
}) {
try {
const { q } = options?.query
console.log("search value", q)
const { q } = options?.query;
console.log('search value', q);
const perpage = Number(options?.query.perpage) || 10;
const page = Number(options?.query.page) || 1;

const searchRecord = {
$text: {
$search: q,
$language: 'en',
$caseSensitive: false
}
$caseSensitive: false,
},
} as FilterQuery<T>;
const total = await this._repository.countDocuments(searchRecord);
const data = await this._repository
Expand All @@ -157,11 +200,11 @@ export class MongoGenericRepository<T> implements IGenericRepository<T> {
currentPage: Number(page),
total: total,
pageSize: perpage,
lastPage: Math.ceil(total / perpage)
}
lastPage: Math.ceil(total / perpage),
},
});
} catch (e) {
return Promise.reject(e);
}
}
}
}
2 changes: 1 addition & 1 deletion src/modules/post/post.controller.ts
Expand Up @@ -79,7 +79,7 @@ export class PostController {
@Param('userId') userId: string,
) {
// const userId = req.user._id;
query = { creator: userId, isDeleted: false };
query = { creator: userId, isDeleted: false, isAdminDeleted: false };
const payload: IGetUserPosts = { ...query };

const response = await this.service.getUserPosts(payload);
Expand Down
45 changes: 33 additions & 12 deletions src/modules/post/post.service.ts
Expand Up @@ -47,11 +47,11 @@ export class PostService {
if (data.description) key['description'] = data.description;
if (data.group) key['group'] = data.group;
if (data.isAdminDeleted === false || data.isAdminDeleted)
if (data.allowDuet === false || data.allowDuet)
key['allowDuet'] = data.allowDuet;
key['isAdminDeleted'] = data.isAdminDeleted;
if (data.allowDuet === false || data.allowDuet)
key['allowDuet'] = data.allowDuet;
if (data.allowStitch === false || data.allowStitch)
key['allowStitch'] = data.allowStitch;
key['isAdminDeleted'] = data.isAdminDeleted;
if (data.isDeleted === false || data.isDeleted)
key['isDeleted'] = data.isDeleted;
if (data.page) key['page'] = data.page;
Expand Down Expand Up @@ -139,14 +139,21 @@ export class PostService {

const { data, pagination } = await this.data.post.findAllWithPagination(
filterQuery,
{ populate: 'creator' },
);

let returnedData = [];

for (let i = 0; i < data.length; i++) {
const postId = data[i]._id.toString();
const likes = await this.data.likes.find({ post: postId });
const comments = await this.data.comments.find({ post: postId });
const likes = await this.data.likes.find(
{ post: postId },
{ isLean: true, populate: 'user' },
);
const comments = await this.data.comments.find(
{ post: postId },
{ isLean: true, populate: 'user' },
);

const newData = {
...data[i]._doc,
Expand Down Expand Up @@ -177,14 +184,21 @@ export class PostService {

const { data, pagination } = await this.data.post.findAllWithPagination(
filterQuery,
{ populate: 'creator' },
);

let returnedData = [];

for (let i = 0; i < data.length; i++) {
const postId = data[i]._id.toString();
const likes = await this.data.likes.find({ post: postId });
const comments = await this.data.comments.find({ post: postId });
const likes = await this.data.likes.find(
{ post: postId },
{ isLean: true, populate: 'user' },
);
const comments = await this.data.comments.find(
{ post: postId },
{ isLean: true, populate: 'user' },
);

const newData = {
...data[i]._doc,
Expand Down Expand Up @@ -242,10 +256,14 @@ export class PostService {
try {
const { postId } = payload;

const post = await this.data.post.findOne({
_id: postId,
isDeleted: false,
});
const post = await this.data.post.findOne(
{
_id: postId,
isDeleted: false,
},
null,
{ populate: 'creator' },
);
if (!post) throw new DoesNotExistsException('Post not found');

return {
Expand Down Expand Up @@ -368,7 +386,10 @@ export class PostService {
const post = await this.data.post.findOne({ _id: postId });
if (!post) throw new DoesNotExistsException('Post not found');

const likes = await this.data.likes.find({ post: postId });
const likes = await this.data.likes.find(
{ post: postId },
{ isLean: true, populate: 'user' },
);

return {
message: 'Likes retrieved successfully',
Expand Down