Reputation: 1451
This is my sample record:
Building id as highlighted in above image, has a subdocument gateways. I am able to find building id but not sure how to push / insert a new object gateway under gateways subdocument.
here is my body for new gateway object to be inserted from request.
{
"gatewayName": "gatewayName",
"gatewayKey": "sampleKey",
"suite": "3300"
}
This is what I am trying currently. It returns the same document.
First I find account, then get building. then Find building based on buildingId provided.
There I need to insert a new gateway object under Gateways subdocument
const account = await Account.findOne({ _id: new ObjectId(req.query.id) });
const allBuildings = account.buildings;
const filteredBuildings = _.filter(allBuildings, { _id: ObjectId(req.query.buildingId) });
const gateways = _.flatMap(filteredBuildings, b => b.gateways);
gateways.push({
"gatewayName": "TD Bank Tower22223",
"gatewayKey": "sdasdasdasd",
"suite": "3300"
}
);
const updatedAccount = await account.save();
console.log(updatedAccount)
res.json(updatedAccount);
Upvotes: 0
Views: 77
Reputation: 1451
I was able to dig through sub documents using even easier method. I am posting answer here so others can use it.
if you want to find embedded sub documents:
var gateway = account.buildings.id(req.params.buildingId).gateways.id(req.params.gatewayId);
using .id(_id) helps to find object by id quicker.
if you want to remove an object from deeply nested subdocument:
account.buildings.id(req.params.buildingId).gateways.id(req.params.gatewayId).devices.pull(req.params.deviceId);
above will remove the element. then you just have to save the document using collectionName.save()
Upvotes: 0
Reputation: 18909
Yes, you can do the find and update in a single findOneAndUpdate
using $elemMatch, $addToSet and the $ operators.
First match on the document id and the building id within the array.
You can then access the matched building using the $
operator and use $addToSet
to insert a new array element.
Example:
const gateway = {
"gatewayName": "gatewayName",
"gatewayKey": "sampleKey",
"suite": "3300"
};
const update = await Account.findOneAndUpdate(
{
_id: new ObjectId(req.query.id),
buildings: {$elemMatch: {_id: {$eq: ObjectId(req.query.buildingId)}}}
},
{
$addToSet: {"buildings.$.gateways": gateway}
},
{
new: true
}
);
Upvotes: 1