diff --git a/apps/meteor/server/main.ts b/apps/meteor/server/main.ts index 893a970578b0..facd1f494e29 100644 --- a/apps/meteor/server/main.ts +++ b/apps/meteor/server/main.ts @@ -1,5 +1,6 @@ import './models/startup'; + /** * ./settings uses top level await, in theory the settings creation * and the startup should be done in parallel diff --git a/apps/meteor/server/models/raw/Rooms.ts b/apps/meteor/server/models/raw/Rooms.ts index 784bd9f4e360..eb70ecf7f7a6 100644 --- a/apps/meteor/server/models/raw/Rooms.ts +++ b/apps/meteor/server/models/raw/Rooms.ts @@ -1462,22 +1462,6 @@ export class RoomsRaw extends BaseRaw implements IRoomsModel { return this.find({ uids: { $size: 2, $in: [uids] }, t: 'd' }); } - findPaginatedByNameOrFnameInIds( - ids: IRoom['_id'][], - filter?: string, - options: FindOptions = {}, - ): FindPaginated> { - const regxp = filter && new RegExp(escapeRegExp(filter), 'i'); - const query: Filter = { - _id: { - $in: ids, - }, - ...(regxp && { $or: [{ name: regxp }, { fname: regxp }] }), - }; - - return this.findPaginated(query, options); - } - // UPDATE addImportIds(_id: IRoom['_id'], importIds: string[]): Promise { const query: Filter = { _id }; @@ -2076,7 +2060,83 @@ export class RoomsRaw extends BaseRaw implements IRoomsModel { return this.updateMany(query, update); } - findDiscussionsByPrid(prid: string, options?: FindOptions): FindCursor { - return this.find({ prid }, options); + findChildrenOfTeam( + teamId: string, + teamRoomId: string, + userId: string, + filter?: string, + options?: FindOptions, + ): AggregationCursor<{ totalCount: { count: number }[]; paginatedResults: IRoom[] }> { + const nameFilter = filter ? new RegExp(escapeRegExp(filter), 'i') : undefined; + return this.col.aggregate<{ totalCount: { count: number }[]; paginatedResults: IRoom[] }>([ + { + $match: { + $and: [ + { + $or: [ + { + teamId, + }, + { prid: teamRoomId }, + ], + }, + ...(nameFilter ? [{ $or: [{ fname: nameFilter }, { name: nameFilter }] }] : []), + ], + }, + }, + { + $lookup: { + from: 'rocketchat_subscription', + let: { + roomId: '$_id', + }, + pipeline: [ + { + $match: { + $and: [ + { + $expr: { + $eq: ['$rid', '$$roomId'], + }, + }, + { + $expr: { + $eq: ['$u._id', userId], + }, + }, + ], + }, + }, + { + $project: { _id: 1 }, + }, + ], + as: 'subscription', + }, + }, + { + $match: { + $or: [ + { t: 'c' }, + { + $expr: { + $ne: [{ $size: '$subscription' }, 0], + }, + }, + ], + }, + }, + { $project: { subscription: 0 } }, + { $sort: options?.sort || { ts: 1 } }, + { + $facet: { + totalCount: [{ $count: 'count' }], + paginatedResults: [ + { $skip: options?.skip || 0 }, // Replace 0 with your skip value + { $limit: options?.limit || 50 }, // Replace 10 with your limit value + ], + }, + }, + ]); } } diff --git a/apps/meteor/server/services/team/service.ts b/apps/meteor/server/services/team/service.ts index c2904dc61310..c0a15216c449 100644 --- a/apps/meteor/server/services/team/service.ts +++ b/apps/meteor/server/services/team/service.ts @@ -1069,30 +1069,12 @@ export class TeamService extends ServiceClassInternal implements ITeamService { throw new Error('error-invalid-team-no-main-room'); } - const [discussionIds, teamRooms] = await Promise.all([ - Rooms.findDiscussionsByPrid(mainRoom._id, { projection: { _id: 1 } }) - .map(({ _id }) => _id) - .toArray(), - Rooms.findByTeamId(team._id, { projection: { _id: 1, t: 1 } }).toArray(), - ]); - - const teamPublicIds = teamRooms.filter(({ t }) => t === 'c').map(({ _id }) => _id); - const teamRoomIds = teamRooms.map(({ _id }) => _id); - const roomIds = await Subscriptions.findByUserIdAndRoomIds(userId, teamRoomIds, { projection: { rid: 1 } }) - .map(({ rid }) => rid) - .toArray(); - - const { cursor, totalCount } = Rooms.findPaginatedByNameOrFnameInIds( - [...new Set([mainRoom._id, ...roomIds, ...discussionIds, ...teamPublicIds])], - filter, + const [ { - skip, - limit, - sort, + totalCount: [{ count: total }], + paginatedResults: data, }, - ); - - const [data, total] = await Promise.all([cursor.toArray(), totalCount]); + ] = await Rooms.findChildrenOfTeam(team._id, mainRoom._id, userId, filter, { skip, limit, sort }).toArray(); return { total, diff --git a/packages/model-typings/src/models/IRoomsModel.ts b/packages/model-typings/src/models/IRoomsModel.ts index 4d116919c908..b0bbbfc35d6b 100644 --- a/packages/model-typings/src/models/IRoomsModel.ts +++ b/packages/model-typings/src/models/IRoomsModel.ts @@ -159,8 +159,6 @@ export interface IRoomsModel extends IBaseModel { findSmallestFederatedRoomInNumberOfUsers(options?: FindOptions): Promise; - findPaginatedByNameOrFnameInIds(ids: IRoom['_id'][], filter?: string, options?: FindOptions): FindPaginated>; - countFederatedRooms(): Promise; incMsgCountById(rid: string, inc: number): Promise; getIncMsgCountUpdateQuery(inc: number, roomUpdater: Updater): Updater; @@ -283,5 +281,11 @@ export interface IRoomsModel extends IBaseModel { getSubscribedRoomIdsWithoutE2EKeys(uid: IUser['_id']): Promise; removeUsersFromE2EEQueueByRoomId(roomId: IRoom['_id'], uids: IUser['_id'][]): Promise; removeUserFromE2EEQueue(uid: IUser['_id']): Promise; - findDiscussionsByPrid(prid: string, options?: FindOptions): FindCursor; + findChildrenOfTeam( + teamId: string, + teamRoomId: string, + userId: string, + filter?: string, + options?: FindOptions, + ): AggregationCursor<{ totalCount: { count: number }[]; paginatedResults: IRoom[] }>; }