Mongoose
Update Documentation
Mongoose Scheme
A group
have many members(ref)
, many expenses
paid by one member(ref)
var groupSchema = new Schema(
{
groupName: { type: String, required: true },
members: [
{
memberId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'user',
},
accepted: { type: Boolean, required: true }
},
],
expenses: [
{
description: { type: String, required: true },
amount: { type: Number, require: true },
payer_id: {
type: mongoose.Schema.Types.ObjectId,
ref: 'user',
require: true,
},
},
],
}
);
Find doc if specific item exists in array
// Get all group where member contains userId
// groupName: 1 means return `groupName` field
group.find(
{ members: { $elemMatch: { memberId: someUserId } } }, // only if members contains userId
{ groupName: 1, members: { $elemMatch: { memberId: someUserId } } }, // projections: groupName, specific user
(error, groups) => {}
);
When there is only 1 attribute filter, you can rewrite
{ members: { $elemMatch: { memberId: someUserId } } }
to
{ 'members.memberId': userId }
Update item in array
// set a user as accepted
group.findOneAndUpdate(
{ _id: groupId, 'members.memberId': userId },
{ $set: { 'members.$.accepted': true } },
(error, updated) => {}
);
Push item in array
// add new expense happens in the group
group.updateOne(
{ _id: group_id },
{ $push: { expenses: newExpenseObj } },
(err, res) => {}
);
Remove item from array
// delete member from group
group.updateOne(
{ _id: groupId },
{ $pull: { members: { memberId: userId } } },
(err, res) => {}
);
Populate Ref
// find all expense with payer name populated within group
group.findOne(
{ _id: groupId },
(error, group) => {}
)
.populate('expenses.payer_id', 'name'); // use XXX.XXX to populate down level, `name` is like projection