Skip to content

Commit

Permalink
[FIX] livechat/rooms endpoint not working with big amount of livechats (
Browse files Browse the repository at this point in the history
#16623)

* Remove aggregate to improve performance

* Use a cursor to run query only once

* Do not use toArray in model

Co-authored-by: Diego Sampaio <chinello@gmail.com>
  • Loading branch information
MarcosSpessatto and sampaiodiego committed Feb 19, 2020
1 parent ffbad58 commit 95e89f6
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 58 deletions.
33 changes: 20 additions & 13 deletions app/livechat/server/api/lib/rooms.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { LivechatRooms } from '../../../../models/server/raw';
import { LivechatRooms, LivechatDepartment } from '../../../../models/server/raw';

export async function findRooms({
agents,
Expand All @@ -16,18 +16,7 @@ export async function findRooms({
sort,
},
}) {
const total = (await LivechatRooms.findRoomsWithCriteria({
agents,
roomName,
departmentId,
open,
createdAt,
closedAt,
tags,
customFields,
})).length;

const rooms = await LivechatRooms.findRoomsWithCriteria({
const cursor = LivechatRooms.findRoomsWithCriteria({
agents,
roomName,
departmentId,
Expand All @@ -44,6 +33,24 @@ export async function findRooms({
},
});

const total = await cursor.count();

const rooms = await cursor.toArray();

const departmentsIds = [...new Set(rooms.map((room) => room.departmentId).filter(Boolean))];
if (departmentsIds.length) {
const departments = await LivechatDepartment.findInIds(departmentsIds, { fields: { name: 1 } }).toArray();

rooms.forEach((room) => {
if (!room.departmentId) {
return;
}
const department = departments.find((dept) => dept._id === room.departmentId);
if (department) {
room.department = department;
}
});
}
return {
rooms,
count: rooms.length,
Expand Down
6 changes: 4 additions & 2 deletions app/models/server/raw/LivechatDepartment.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { BaseRaw } from './BaseRaw';

export class LivechatDepartmentRaw extends BaseRaw {


findInIds(departmentsIds, options) {
const query = { _id: { $in: departmentsIds } };
return this.find(query, options);
}
}
58 changes: 15 additions & 43 deletions app/models/server/raw/LivechatRooms.js
Original file line number Diff line number Diff line change
Expand Up @@ -1099,73 +1099,45 @@ export class LivechatRoomsRaw extends BaseRaw {
}

findRoomsWithCriteria({ agents, roomName, departmentId, open, createdAt, closedAt, tags, customFields, options = {} }) {
const match = {
$match: {
t: 'l',
},
const query = {
t: 'l',
};
if (agents) {
match.$match.$or = [{ 'servedBy._id': { $in: agents } }, { 'servedBy.username': { $in: agents } }];
query.$or = [{ 'servedBy._id': { $in: agents } }, { 'servedBy.username': { $in: agents } }];
}
if (roomName) {
match.$match.fname = new RegExp(roomName, 'i');
query.fname = new RegExp(roomName, 'i');
}
if (departmentId) {
match.$match.departmentId = departmentId;
query.departmentId = departmentId;
}
if (open !== undefined) {
match.$match.open = { $exists: open };
query.open = { $exists: open };
}
if (createdAt) {
match.$match.ts = {};
query.ts = {};
if (createdAt.start) {
match.$match.ts.$gte = new Date(createdAt.start);
query.ts.$gte = new Date(createdAt.start);
}
if (createdAt.end) {
match.$match.ts.$lte = new Date(createdAt.end);
query.ts.$lte = new Date(createdAt.end);
}
}
if (closedAt) {
match.$match.closedAt = {};
query.closedAt = {};
if (closedAt.start) {
match.$match.closedAt.$gte = new Date(closedAt.start);
query.closedAt.$gte = new Date(closedAt.start);
}
if (closedAt.end) {
match.$match.closedAt.$lte = new Date(closedAt.end);
query.closedAt.$lte = new Date(closedAt.end);
}
}
if (tags) {
match.$match.tags = { $in: tags };
query.tags = { $in: tags };
}
if (customFields) {
match.$match.$and = Object.keys(customFields).map((key) => ({ [`livechatData.${ key }`]: new RegExp(customFields[key], 'i') }));
}
const sort = { $sort: options.sort || { name: 1 } };
const firstParams = [match, sort];
if (options.offset) {
firstParams.push({ $skip: options.offset });
query.$and = Object.keys(customFields).map((key) => ({ [`livechatData.${ key }`]: new RegExp(customFields[key], 'i') }));
}
if (options.count) {
firstParams.push({ $limit: options.count });
}
const lookup = {
$lookup: {
from: 'rocketchat_livechat_department',
localField: 'departmentId',
foreignField: '_id',
as: 'department',
},
};
const unwind = {
$unwind: {
path: '$department',
preserveNullAndEmptyArrays: true,
},
};
const params = [...firstParams, lookup, unwind];
if (options.fields) {
params.push({ $project: options.fields });
}
return this.col.aggregate(params).toArray();
return this.find(query, { sort: options.sort || { name: 1 }, skip: options.offset, limit: options.count });
}
}

0 comments on commit 95e89f6

Please sign in to comment.