Skip to content

Commit

Permalink
fix: improve timeline query (#849)
Browse files Browse the repository at this point in the history
* fix: rename timeline config collection

* fix: update timeline config migration

* fix: improvement timeline query

---------

Co-authored-by: Abdul Hakim <[email protected]>
  • Loading branch information
abdulhakim2902 and abdulhakim2902 authored Apr 16, 2023
1 parent dfb24cc commit 5c17d23
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 86 deletions.
155 changes: 97 additions & 58 deletions src/application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ import {getFilePathFromSeedData, upload, UploadType} from './utils/upload';
import fs, {existsSync} from 'fs';
import {FriendStatusType} from './enums';
import {UpdatePeopleProfileJob} from './jobs';
import {MentionUser, SelectedUser, TimelineConfig} from './models';
import {ConfigData, MentionUser, SelectedUser} from './models';

const jwt = require('jsonwebtoken');

Expand Down Expand Up @@ -243,7 +243,12 @@ export class MyriadApiApplication extends BootMixin(
const env = this.options?.environment;
if (!this.options?.skipMigrateSchema) await super.migrateSchema(options);
if (options?.existingSchema === 'drop') return this.databaseSeeding(env);
await Promise.all([this.doMigrateExperience(), this.doMigratePost()]);
await Promise.all([
this.doMigrateExperience(),
this.doMigrateExperiencePost(),
this.doMigrateTimelineConfig(),
this.doMigratePost(),
]);
}

async databaseSeeding(environment: string): Promise<void> {
Expand Down Expand Up @@ -505,34 +510,21 @@ export class MyriadApiApplication extends BootMixin(

async doMigrateExperience(): Promise<void> {
if (!this.doCollectionExists('experience')) return;
const {
experienceRepository,
experiencePostRepository,
postRepository,
userExperienceRepository,
timelineConfigRepository,
} = await this.repositories();
const {experienceRepository} = await this.repositories();

const [
{count: totalPostExp},
{count: totalExperience},
{count: totalUserExperience},
] = await Promise.all([
experiencePostRepository.count(),
const [{count: totalExperience}] = await Promise.all([
experienceRepository.count({
selectedUserIds: {
exists: true,
},
}),
userExperienceRepository.count(),
]);

const bar = this.initializeProgressBar('Start Migrate Experience');

const promises = [];
const barSize = totalExperience + totalPostExp + totalUserExperience;

bar.start(barSize - 1);
bar.start(totalExperience - 1);
for (let i = 0; i < totalExperience; i++) {
const [experience] = await experienceRepository.find({
limit: 1,
Expand Down Expand Up @@ -577,7 +569,25 @@ export class MyriadApiApplication extends BootMixin(
bar.update(i);
}

for (let i = 0; i < totalPostExp; i++) {
bar.stop();

await Promise.allSettled(promises);
}

async doMigrateExperiencePost(): Promise<void> {
if (!this.doCollectionExists('experience-post')) return;
const {experienceRepository, experiencePostRepository, postRepository} =
await this.repositories();

const [{count: totalExperiencePost}] = await Promise.all([
experiencePostRepository.count(),
]);

const bar = this.initializeProgressBar('Start Migrate Experience Post');
const promises = [];

bar.start(totalExperiencePost - 1);
for (let i = 0; i < totalExperiencePost; i++) {
const [experiencePost] = await experiencePostRepository.find({
limit: 1,
skip: i,
Expand Down Expand Up @@ -613,15 +623,36 @@ export class MyriadApiApplication extends BootMixin(
}
}

bar.update(totalExperience + i + 1);
bar.update(i);
}

const configs = new Map<string, TimelineConfig>();
bar.stop();

for (let i = 0; i < totalUserExperience; i++) {
const [userExperience] = await userExperienceRepository.find({
await Promise.allSettled(promises);
}

async doMigrateTimelineConfig(): Promise<void> {
if (!this.doCollectionExists('timeline-config')) return;
const {userRepository, userExperienceRepository, timelineConfigRepository} =
await this.repositories();

const {count: totalUser} = await userRepository.count();
const bar = this.initializeProgressBar('Start Migrate Timeline Config');
const promises = [];

bar.start(totalUser - 1);
for (let i = 0; i < totalUser; i++) {
const [user] = await userRepository.find({
limit: 1,
skip: i,
});

if (!user) continue;

const userExperiences = await userExperienceRepository.find({
where: {
userId: user.id,
},
include: [
{
relation: 'experience',
Expand All @@ -632,42 +663,50 @@ export class MyriadApiApplication extends BootMixin(
],
});

if (!userExperience) continue;
const experience = userExperience.experience;
if (!experience) continue;
const users = experience.users ?? [];
const timelineConfig = await (configs.get(userExperience.userId) ??
timelineConfigRepository
.findOne({
where: {userId: userExperience.userId},
})
.then(result => {
if (result) return result;
return timelineConfigRepository.create({
userId: userExperience.userId,
});
}));

timelineConfig.data[experience.id] = {
timelineId: experience.id,
allowedTags: experience.allowedTags,
prohibitedTags: experience.prohibitedTags,
peopleIds: experience.people.map(e => e.id),
userIds: users.map(e => e.id),
selectedUserIds: experience.selectedUserIds,
visibility: experience.visibility,
createdBy: experience.createdBy,
createdAt: 0,
};

configs.set(userExperience.userId, timelineConfig);

bar.update(totalExperience + totalPostExp + i + 1);
}
if (userExperiences.length === 0) continue;

configs.forEach(value => {
promises.push(timelineConfigRepository.update(value));
});
const timelineConfig = await timelineConfigRepository
.findOne({
where: {
userId: user.id,
},
})
.then(result => {
if (result) return result;
return timelineConfigRepository.create({
data: {},
userId: user.id,
});
});

const data: ConfigData = {};

for (const userExperience of userExperiences) {
const experience = userExperience.experience;
if (!experience) continue;
const users = experience.users ?? [];
data[experience.id] = {
timelineId: experience.id,
allowedTags: experience.allowedTags,
prohibitedTags: experience.prohibitedTags,
peopleIds: experience.people.map(e => e.id),
userIds: users.map(e => e.id),
selectedUserIds: experience.selectedUserIds,
visibility: experience.visibility,
createdBy: experience.createdBy,
createdAt: 0,
};
}

promises.push(
timelineConfigRepository.updateById(timelineConfig.id, {
data,
userId: user.id,
}),
);

bar.update(i + 1);
}

bar.stop();

Expand Down
2 changes: 1 addition & 1 deletion src/models/timeline-config.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export interface ConfigData {
settings: {
strictObjectIDCoercion: true,
mongodb: {
collection: 'transactions',
collection: 'timelineConfigs',
},
},
})
Expand Down
69 changes: 42 additions & 27 deletions src/services/filter-builder.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
import {
ActivityLog,
Comment,
ConfigData,
Experience,
ExperiencePost,
Friend,
Expand Down Expand Up @@ -1408,26 +1409,26 @@ export class FilterBuilderService {
private async timelineByExperience(
currentUserId: string,
config: Timeline,
approvedIds: string[],
blockedIds: string[],
selected?: SelectedUser,
): Promise<Where<Post>[]> {
const experienceUserIds: string[] = [];
const {allowedTags, prohibitedTags, peopleIds, userIds} = config;
const [blockedIds, approvedIds, expFriends] = await Promise.all([
this.friendService.getFriendIds(currentUserId, FriendStatusType.BLOCKED),
this.friendService.getFriendIds(currentUserId, FriendStatusType.APPROVED),
const [expFriends, accountSettings] = await Promise.all([
this.friendService.find({
where: {
requestorId: currentUserId,
requesteeId: {inq: userIds},
status: FriendStatusType.APPROVED,
},
}),
this.accountSettingRepository.find({
where: {userId: {inq: userIds}},
}),
]);
const expFriendIds = expFriends.map(friend => friend.requesteeId);
const blocked = pull(blockedIds, ...expFriendIds, ...approvedIds);
const accountSettings = await this.accountSettingRepository.find({
where: {userId: {inq: userIds}},
});

if (accountSettings.length > 0) {
for (const accountSetting of accountSettings) {
Expand Down Expand Up @@ -1506,7 +1507,7 @@ export class FilterBuilderService {
{visibility: VisibilityType.SELECTED},
],
},
// Visibility FRIEND
// // Visibility FRIEND
{
and: [
{tags: {nin: prohibitedTags}} as Where,
Expand Down Expand Up @@ -1546,12 +1547,6 @@ export class FilterBuilderService {
{createdBy: currentUserId},
],
},
{
and: [
{tags: {nin: prohibitedTags}} as Where,
{createdBy: this.currentUser[securityId]},
],
},
{
and: [
{tags: {nin: prohibitedTags}} as Where,
Expand Down Expand Up @@ -1733,25 +1728,37 @@ export class FilterBuilderService {
if (!timelineConfig) return {id: ''};

const timelineFilter: Where<Post>[] = [];
const timelineConfigData: ConfigData = {};

if (experienceId) {
const config = timelineConfig.data[experienceId.toString()];
if (config) {
const filter = await this.timelineVisibilityFilter(
currentUserId,
config,
);
timelineFilter.push(...filter);
timelineConfigData[experienceId.toString()] = config;
}
} else {
for (const experiencId in timelineConfig.data) {
const config = timelineConfig.data[experiencId];
const filter = await this.timelineVisibilityFilter(
currentUserId,
config,
);
timelineFilter.push(...filter);
}
Object.assign(timelineConfigData, timelineConfig.data);
}

const [friendIds, blockedIds] = await Promise.all([
this.friendService.getFriendIds(
currentUserId,
FriendStatusType.APPROVED,
),
this.friendService.getFriendIds(
currentUserId,
FriendStatusType.BLOCKED,
),
]);

for (const experiencId in timelineConfigData) {
const config = timelineConfigData[experiencId];
const filter = await this.timelineVisibilityFilter(
currentUserId,
config,
friendIds,
blockedIds,
);
timelineFilter.push(...filter);
}

if (timelineFilter.length === 0) {
Expand Down Expand Up @@ -1786,6 +1793,8 @@ export class FilterBuilderService {
private async timelineVisibilityFilter(
currentUserId: string,
config: Timeline,
friendIds: string[],
blockedIds: string[],
): Promise<Where<Post>[]> {
const creator = config.createdBy;
const visibility = config.visibility;
Expand Down Expand Up @@ -1821,7 +1830,13 @@ export class FilterBuilderService {
}
}

return this.timelineByExperience(currentUserId, config, selected);
return this.timelineByExperience(
currentUserId,
config,
friendIds,
blockedIds,
selected,
);
}

private orderSetting(query: Query): string[] {
Expand Down

0 comments on commit 5c17d23

Please sign in to comment.