mongoose push nested subdocument array - arrays

i need to push data in nested subdocument array:
this is my Json:
[
{
_id: "56cbe9727bab33a413216dd4",
company_name: "Star",
__v: 0,
created_at: "2016-02-23T05:09:06.754Z",
plan: [
{
plan_name: "Mediclassic",
plan_type: "Individual",
_id: "56cbe9727bab33a413216dd5",
created_at: "2016-02-23T05:09:06.756Z",
rate_card: [
{
zone: "zone-2",
suminsured: 150000,
premium: 2874,
size: "1A",
_id: "56cbe9727bab33a413216dd6",
benefits: {
hospitals: true,
copay: true,
cashless_hospital: true,
existing_disease_cover: true
},
age: {
min: "5M",
max: 35
}
}
]
}
]
}
]
I need to push my data in rate_card, i have tried something but its not working
below is my code:
AngularController.js
$scope.RateCardCreateAction = function(){
$scope.params = $routeParams.id;
console.log($scope.insurance.plan.rate_card);
$http.put('/auth/insurance-list/plan/new/rate_card/' + $scope.params, $scope.insurance.plan.rate_card).success(function(response){
console.log(response);
refresh();
});
};
mainRoutes.js
// New Rate Card
router.put('/secure/insurance-list/plan/new/rate_card/:id', function(req, res){
var id = req.params.id;
Insurance.update({'plan._id':id}, {$push :
{
'rate_card' : {
'zone' : req.body.zone,
'suminsured' : req.body.suminsured,
'premium' : req.body.premium,
'size' : req.body.size,
'age' : {
'min' : req.body.age.min,
'max' : req.body.age.max
},
'benefits' : {
'hospitals' : req.body.benefits.hospitals,
'cashless_hospital' : req.body.benefits.cashless_hospital,
'copay' : req.body.benefits.copay,
'existing_disease_cover' : req.body.benefits.existing_disease_cover
}
}
}
}, {upsert: true}, function(err, docs){
res.json(docs);
console.log(docs);
});
});
Here i need to push data to rate_card, but data is not storing in subdocument array, here am getting plan id and trying to push but is not working
in server response am getting this { ok: 0, n: 0, nModified: 0 }

Try this, i hope this will help you
router.put('/secure/insurance-list/plan/new/rate_card/:id/:id2', function(req, res){
var id = req.params.id;
var id2 = req.params.id2;
Insurance.update({_id:id, 'plan._id':id2}, {$push :
{'plan.$.rate_card' : req.body}
}, {upsert: true}, function(err, docs){
res.json(docs);
console.log(docs);
});
});

If somehow your inserted value is not present then it would be great to use $addToSet.
var updateArr = {
'roomUsers':{
userId:req.session.userInfo._id,
requestDate:Date.now(),
status:1
}
};
roomInfo.findOneAndUpdate({_id:roomId}, {$addToSet:updateArr}, (err, result) => {
if (!err && result) {
res.send({
status:true
});
}
else{
res.send({
status:false
});
}
});

I got it done using below update query:
db.insurance.updateOne(
{
_id: ObjectId('60659595afcb710627e3fad7')
},
{
$push: {
"plan.$[element].rate_card": {
$each: [
{ _id: ObjectId('6062bd90c5a1d66fdd2c91bc'), premium: 2874, size: "1A" },
{ _id: ObjectId('6062bd90c5a1d66fdd2c91bc'), premium: 2874, size: "1A" }]
}
}
},
{
arrayFilters: [{ "element._id": ObjectId('6065a35ee1e5f1153504e861') }]
}
);
In $each you need to add your array of object.
element._id is your subdocument id (above case is plan _id).

Related

How to update object inside array inside object?

I have the following Mongooose schema:
{
_id: {
type: String,
required: true
},
semesters: [
{
_id: {
type: String,
required: true
},
grades: [
{
subject: String,
literalGrade: String,
grade: Number,
credits: Number
}
]
}
]
}
I want to be able to update one grade that is inside semester's grades object using its id. I tried using MongoDb new multiple positional operator to no avail.
This is my current snippet:
User.findOneAndUpdate(
{
_id: req.params.user_id,
"semesters._id": req.params.semester_id
},
{
$set: {
"semesters.$[x].grades.$[y].subject": req.body.grades.subject,
"semesters.$[x].grades.$[y].literalGrade": req.body.grades.literalGrade,
"semesters.$[x].grades.$[y].grade": req.body.grades.grade,
"semesters.$[x].grades.$[y].credits": req.body.grades.credits
}
},
{
arrayFilters: [
{ "x._id": req.params.semester_id },
{ "y._id": req.params.grade_id }
]
},
(err, user) => {
if (err) return res.json(err);
res.send({
message: "Updated grade",
data: user
});
}
);
Couldn't get any results with the MongoDb positional operator, but found a way to programmatically do it with the help of Naing Lin Aung's answer. Here is the solution:
User.findOne(
{
_id: req.params.user_id,
"semesters.grades._id": req.params.grade_id
},
{ "semesters.$.grades": 1 },
(err, user) => {
if (err) return res.json(err);
let grades = user.semesters[0].grades;
let index = null;
for (let t in grades) {
if (grades[t]._id == req.params.grade_id) {
index = t;
break;
}
}
let grade = grades[index];
grade.subject = req.body.grades.subject;
grade.literalGrade = req.body.grades.literalGrade;
grade.grade = req.body.grades.grade;
grade.credits = req.body.grades.credits;
user.save(function(err) {
if (err) return res.json(err);
res.json({
message: "Updated grade",
data: user
});
});
}
);
You can take advantage of $[] syntax with arrayFilters
refer this link : https://docs.mongodb.com/manual/reference/operator/update/positional-all
db.col.update(
{ _id: req.params.user_id },
{ $set: { "semesters.$[cond1].grades.$[cond2].subject": req.body.grades.subject } },
{ arrayFilters: [ { "cond1._id": req.params.semester_id }, { "cond2._id": req.params.grade_id } ] })
You can similarly update other fields in $set

Multiple arguments in mongodb aggregate

I'm trying to get multiple arguments in my mongodb, My code here gets the distinct values for date and count it, but how can I add another argument to get for example another set of distinct and count.
Example:
Here is the output of my code:
[ { _id: '05-09-2019', count3: 1 },
{ _id: '06-09-2019', count3: 1 },
{ _id: '06-21-2019', count3: 1 },
{ _id: '06-30-2019', count3: 5 },]
How can I achieve this:
[ { _id: '05-09-2019', count: 1, branch: America, count2: 1},
{ _id: '06-09-2019', count: 1, branch: Germany,count2: 1},
{ _id: '06-21-2019', count: 1, branch: Philippines,count2: 1},
{ _id: '06-30-2019', count: 5 , branch: Vietnam,count2: 1},]
Here is my code to get the distinct values of date while counting it:
router.get('/blooddonationarea', function(req, res) {
Blooddonation.aggregate([{$group: {_id : "$date" , count :{$sum:1}}},{$sort: {_id: 1}}],function(err, date) {
res.json({ success: true, date: date });
//console.log(date);
});
});
I tried inserting this after the [] clause but it doesn't get the values at all
[{ $match: { branch: { $eq: 'Rizal' } } },{$group: {_id : "$date" , count2 :{$sum:1}}},{$sort: {_id: 1}}]
Here is the sample document:
_id:5c1f47dd59cdd931f4ce98ae
blood_product_donated:"Whole Blood"
branch:"Rizal"
deferral_type:"permanent"
date:"10-22-2019"
You could start with grouping the documents by both the date and branch keys, then a further pipeline step where you only group by the
date key on the documents from the previous pipeline. Following this example will give you the desired result:
router.get('/blooddonationarea', (req, res) => {
Blooddonation.aggregate([
{ '$group': {
'_id': { 'date': '$date', 'branch': '$branch' },
'count': { '$sum': 1 }
} },
{ '$group': {
'_id': '$_id.date',
'count': { '$sum': '$count' },
'branch': { '$first': '$_id.branch' },
'count2': { '$first': '$count' }
} },
{ '$sort': { '_id': 1 } }
], (err, date) => {
console.log(date);
if (err) throw err
res.json({ success: true, date });
});
});

Mongoose does not update my array in the database

I'm trying to update my collection with mongoose.
This is my Schema:
var FamilySchema = mongoose.Schema({
construction: {
type: Array,
default: [
["foundry", 0],
["farm", 0],
["sawmill", 0]
]
}
});
And this is my code:
app.put('/construction/updateConstruction/:id', (req, res) => {
let id = req.params.id;
Family.findById(id, (err, familiaDB) => {
if (err) {
return res.status(500).json({
ok: false,
err
});
}
if (!familiaDB) {
return res.status(400).json({
ok: false,
err
});
}
// I want to update the value of the posicion 0 in the array.
familiaDB.construction[0][1] = 1;
familiaDB.save();
console.log(familiaDB);
});
});
Result in console.log after making the request:
Escuchando puerto: 3000
Base de datos ONLINE
{ state: true,
construction:
[ [ 'foundry', 1 ],
[ 'farm', 0 ],
[ 'sawmill', 0 ],
_id: 5bb8d69c604625211c572ada,
__v: 0 }
In console.log everything is fine and updated, but in my db it is not updated. I have checked it many times in robomongo and never updates it.
The quickest way to do this would be with findOneAndUpdate:
Family.findOneAndUpdate(
{ _id: mongoose.Types.ObjectId("YOURID") },
{ $set: { 'construction.0.1': 'YourValue' }}
)
This will do it in one statement.
Now instead of doing this by index you can do it with $elemMatch and update the correct one via:
Family.findOneAndUpdate(
{_id: ObjectId("YOURID"), 'cons': { $elemMatch: { '0': 'foundry' }}},
{ $set: { 'cons.$.1': 'YourValue' } }
)

Can't Store Nested JSON Array to MongoDB Using Mongoose

I have JSON on Postman like this:
{
"hostname": [
{
"item": [
{
"system": "10l313",
"severity": "2"
},
{
"system": "2131414",
"severity": "3"
}
]
},
{
"item": [
{
"system": "4234235",
"severity": "4"
}
]
}
]
}
I want to create new collections in mongodb from json above. It's just a little picture of the actual json array, the above json array can contain an enormous array. I am confused how to save as many json arrays using mongoose, do i have to loop as much as array length or is there other easier way?
mongoose schema:
var ItemSchema = new Schema({
_id: mongoose.Schema.Types.ObjectId,
system: {
type: String
},
severity: {
type: Number
}
})
var VulnSchema = new Schema({
hostname: [{
item: [{ItemSchema}]
}]
});
controller:
exports.create_vulnerabilities = function (req, res) {
var vuln = new Vuln ({
_idFIle: mongoose.Types.ObjectId(),
hostname: req.body.hostname
});
vuln.save()
.then(result => {
res.status(201).json({
result
});
})
.catch(err => {
console.log(err);
res.status(500).json({
error: err
});
});
};
I have tried running my code but the result is like this. The problem is system and severity attribute are not stored in mongodb.
{
"_id" : ObjectId("5b4c39a301651a0fc047bec7"),
"hostname" : [
{
"_id" : ObjectId("5b4c39a301651a0fc047beca"),
"item" : [
{
"_id" : ObjectId("5b4c39a301651a0fc047becc")
},
{
"_id" : ObjectId("5b4c39a301651a0fc047becb")
}
]
},
{
"_id" : ObjectId("5b4c39a301651a0fc047bec8"),
"item" : [
{
"_id" : ObjectId("5b4c39a301651a0fc047bec9")
}
]
}
],
"__v" : 0
}
Please help me. thank you
Change
var VulnSchema = new Schema({
hostname: [{
item: [{ItemSchema}]
}]
});
to
var VulnSchema = new Schema({
hostname: [{
item: [ItemSchema]
}]
});
Example try running this:
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test');
const Schema = mongoose.Schema,ObjectId = Schema.ObjectId;
var ItemSchema = new Schema({
_id: mongoose.Schema.Types.ObjectId,
system: {
type: String
},
severity: {
type: Number
}
})
var VulnSchema = new Schema({
hostname: [{
item: [ItemSchema]
}]
});
const Vuln = mongoose.model('Vuln', VulnSchema);
var hostname = [
{
"item": [
{
"system": "10l313",
"severity": "2"
},
{
"system": "2131414",
"severity": "3"
}
]
},
{
"item": [
{
"system": "4234235",
"severity": "4"
}
]
}
]
var vuln = new Vuln ({
_idFIle: mongoose.Types.ObjectId(),
hostname: hostname
});
vuln.save()
.then(result => {
console.log(JSON.stringify(result))
})
.catch(err => {
console.log(err);}
);

How to remove Object from array using mongoose

I'm trying to remove an object from an array in a document using mongoose.
The Schema is the following:
var diveSchema = new Schema({
//irrelevant fields
divers: [{
user: { type: Schema.Types.ObjectId, ref: 'User', required: true },
meetingLocation: { type: String, enum: ['carpool', 'onSite'], required: true },
dives: Number,
exercise: { type: Schema.Types.ObjectId, ref: 'Exercise' },
}]
});
a possible entry can be
{
//irrelevant fields
"divers": [
{
"_id": "012345678",
"user": "123456789",
"meetingLocation": "carpool",
"exercise": "34567890",
},
{
"_id": "012345679",
"user": "123456780",
"meetingLocation": "onSite",
"exercise": "34567890",
}
]
}
Say I want to remove the entry where user is 123456789 (note I do not know the _id at this point).
How do I do this correctly?
I tried the following:
var diveId = "myDiveId";
var userIdToRemove = "123456789"
Dive.findOne({ _id: diveId }).then(function(dive) {
dive.divers.pull({ user: userIdToRemove });
dive.save().then(function(dive) {
//do something smart
});
});
This yieled no change in the document.
I also tried
Dive.update({ _id: diveId }, { "$pull": { "divers": { "diver._id": new ObjectId(userIdToRemove) } } }, { safe: true }, function(err, obj) {
//do something smart
});
With this I got as result that the entire divers array was emptied for the given dive.
What about this?
Dive.update({ _id: diveId }, { "$pull": { "divers": { "user": userIdToRemove } }}, { safe: true, multi:true }, function(err, obj) {
//do something smart
});
I solve this problem using this code-
await Album.findOneAndUpdate(
{ _id: albumId },
{ $pull: { images: { _id: imageId } } },
{ safe: true, multi: false }
);
return res.status(200).json({ message: "Album Deleted Successfully" });
Try this
Dive.update({ _id: diveId },{"$pull": { "drivers": {"user": "123456789"}}})
Try this async code
var diveId = "myDiveId";
var userIdToRemove = "123456789"
const dive=await Dive.findOne({ _id: diveId })
await dive.divers.pull({ user: userIdToRemove });
await dive.save();
Use this with try/catch:
await Group.updateOne(
{ _id: groupId },
{ $pull: { members: {id: memberId }}}
);

Resources