I am building an auto task manager that will automatically assign a task to users with the same role as the role of the task. Right now I am getting the total number of users with the same role as the task and then use math.random()
to generate a number from 0 to the length of the users that have the same role and the assign the task to that random user. This isn't efficient as a user can have 10 tasks and another user has just 4 tasks. Is there a way I can assign tasks sequentially to all the users with the same role with the task??
This is the code to that creates a new task:
exports.createNewTask = async (req, res) => {
try {
let task = new Task({
title: req.body.title,
description: req.body.description,
role: req.body.role,
priority:req.body.priority
});
let role = req.body.role;
let user = await User.find({ role: role });
if(user.length == 0) {
res.status(500).json({message:"Please Create a User With this role" });
}
let random = Math.floor(Math.random() * user.length);
let assignedUser = user[random]._id;
task.user = assignedUser;
let assignedTask = await task.save()
res.status(200).json({ assignedTask });
} catch (err) {
console.log(err);
res.status(500).json({ error: err });
}
};
i'd add a new field to
User
such asNumTasksAssigned
which would keep a count of how many tasks a user has. if you don't like to manage this count manually, you could also get this count by doing a$lookup
when retrieving the users for a given role.when getting the list of users for a given role, retrieve them sorted in ascending order by the
NumTasksAssigned
field. also limit the number of users returned by how many tasks you have at hand.iterate over the user list and assign tasks to users and increase their task count.
if the number of tasks at hand is greater than the amount of users retrieved, don't break the loop and keep assigning until there are no more tasks to assign.
the main problem with this approach is that users who already had some tasks would get more tasks assigned to them.
we could come up with some algorithm to prevent this from happening and assign tasks evenly. but it may not be a complication you'd wanna deal with.
update: added lookup query
var numTasks = 10;
var roleName = "some role";
db.users.aggregate([
{
$match: { role: roleName }
},
{
$lookup: {
from: "tasks",
localField: "_id",
foreignField: "user",
as: "tasks"
}
},
{
$addFields: {
tasks: { $size: "$tasks" }
}
},
{
$sort: { tasks: 1 }
},
{
$limit: numTasks
}
])