I am creating a project using Node.js, where I have two models: User and Project.
Here's the Schema for Project model:
const ProjectSchema = new mongoose.Schema({
name: {
type: String,
maxlength: 50,
required: true,
},
description: {
type: String,
maxlength: 800,
required: true
},
contributors: [{
type: mongoose.Schema.Types.ObjectId,
ref: "User"
}],
});
Now, for a project, I want to check if the current user is already present in the project's contributors. If the user is not present, then add the user, otherwise, Ignore.
How can I check that in an efficient manner?
CodePudding user response:
mongoose offers you the aggregate method which does pretty everything, in your case:
const projects = ProjectModel.aggregate([
{ $match: {/* query for matching a small size of projects first(you should definitely do this) */} },
{ $unwind: "$contributors" },
{ $project: { contributor: "$contributors" } }, // This stage is actually optional
{ $match: { "contributor._id": /* contributor id you want to check */ } },
{ $count: "projects" }
]);
Now you can just check the variable and see how many projects have the user in their contributors array
I tested this dataset:
[{
"_id": 1,
"name": "Project1",
"contributors": [{
"_id": 11,
"name": "user1"
}, {
"_id": 22,
"name": "user2"
}]
}, {
"_id": 2,
"name": "Project2",
"contributors": [{
"_id": 22,
"name": "user3"
}, {
"_id": 44,
"name": "user4"
}]
}]
With this query:
const projects = ProjectModel.aggregate([
{ $match: { _id: 1 } },
{ $unwind: "$contributors" },
{ $project: { contributor: "$contributors" } },
{ $match: { "contributor._id": 22 } },
{ $count: "projects" }
]);
The result:
[{
"projects": 1
}]
CodePudding user response:
Query
- find the project
- check if user
_id
is on the contributors array - if it is do nothing (keep old value)
- else add the new user
- replace
2
with the userid
and{"_id": 2}
with the user document
*there is no performance problem here, it will be max 1 project i guess with that _id
, you only do 1 test to see if its already contributor.
update(
{"_id": {"$eq": 1}}, //find the project
[{"$set":
{"contributors":
{"$cond":
[{"$in": [2, "$contributors._id"]}, "$contributors",
{"$concatArrays": ["$contributors", [{"_id": 2}]]}]}}}])