Skip to content

Commit 96478f4

Browse files
committed
updated projectManagerList query efficiency
1 parent ea80291 commit 96478f4

File tree

1 file changed

+33
-10
lines changed

1 file changed

+33
-10
lines changed

backend/controllers/user.controller.js

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ UserController.admin_list = async function (req, res) {
4242
}
4343
};
4444

45-
// Get list of Users with accessLevel 'admin' or 'superadmin' and also managed projects with GET
4645
UserController.projectManager_list = async function (req, res) {
4746
const { headers } = req;
4847

@@ -55,24 +54,48 @@ UserController.projectManager_list = async function (req, res) {
5554
managedProjects: { $exists: true, $type: 'array', $not: { $size: 0 } },
5655
});
5756

58-
const updatedProjectManagers = [];
57+
// Filter out managers with empty arrays early
58+
const validProjectManagers = projectManagers.filter(
59+
(manager) => manager.managedProjects && manager.managedProjects.length > 0,
60+
);
5961

60-
for (const projectManager of projectManagers) {
61-
const projectManagerObj = projectManager.toObject();
62+
if (validProjectManagers.length === 0) {
63+
return res.status(200).send([]);
64+
}
65+
66+
// Collect all unique project IDs to fetch in one query
67+
const allProjectIds = new Set();
68+
validProjectManagers.forEach((manager) => {
69+
manager.managedProjects.forEach((projectId) => {
70+
// Filter out invalid project IDs (non-string or obviously invalid values)
71+
if (typeof projectId === 'string' && projectId !== 'false' && projectId.length > 0) {
72+
allProjectIds.add(projectId);
73+
}
74+
});
75+
});
76+
77+
// Fetch all projects in a single query
78+
const projects = await Project.find({ _id: { $in: Array.from(allProjectIds) } });
79+
80+
// Create a map for O(1) lookup
81+
const projectMap = new Map();
82+
projects.forEach((project) => {
83+
projectMap.set(project._id.toString(), project.name);
84+
});
6285

63-
/* Due to the way MongoDB searches for non-empty arrays, sometimes an empty array gets passed
64-
so we need to check if managedProjects is empty */
65-
if (projectManagerObj.managedProjects.length === 0) continue;
86+
const updatedProjectManagers = [];
6687

88+
for (const projectManager of validProjectManagers) {
89+
const projectManagerObj = projectManager.toObject();
6790
projectManagerObj.isProjectMember = true;
6891
const projectNames = [];
6992

7093
for (const projectId of projectManagerObj.managedProjects) {
7194
// using try-catch block because old user data had invalid strings (aka 'false') for ProjectIds
7295
try {
73-
const projectDetail = await Project.findById(projectId);
74-
if (projectDetail && projectDetail.name) {
75-
projectNames.push(projectDetail.name);
96+
const projectName = projectMap.get(projectId.toString());
97+
if (projectName) {
98+
projectNames.push(projectName);
7699
} else {
77100
console.warn('Project detail is null, cannot access name');
78101
}

0 commit comments

Comments
 (0)