Save() not saving nested properties - mongodb

I am new in mongo. I need to update one nested field in MongoDB model. This is my code: -
const employee = await empModel.searchData(Query);
countryArray.push({lang: 'eng', result 100});
countryArray.push({lang: 'german', result 99});
employee[0].country = countryArray;
employee[0].markModified('country');
employee[0].save();
Schema of empModel:
onst mongoSchema = new Schema({
empId: [{
type: Schema.Types.ObjectId
}],
country:[{
lang:String,
result:Number
}],
projectId: {
type: String,
required: true
}
});

Use simple update query instead of find and the update
static async updateData(query, countryArray) {
const updateData= await this.update(query, { $set: { country: countryArray }});
console.log(updated successfully')
return 'Updated successfully'
}
const countryArray = []
countryArray.push({lang: 'eng', result 100})
countryArray.push({lang: 'german', result 99})
const update = await empModel.updateData(Query, countryArray)

Related

Why is my mongoose populate not retrieving the nested array?

I have the following mongoose schemas:
const CategoriesSchema = new mongoose.Schema(
{
sites: [
{
site: {
type: ObjectId,
ref: "Sites",
}
}
],
);
mongoose.model("Categories", CategoriesSchema, 'organizer-categories');
And:
const SitesSchema = new Schema({
url: {
type: String,
required: true,
},
img: {
type: String,
},
});
mongoose.model("Sites", SitesSchema, "organizer-sites");,
The following function is supposed to create a new site in mongodb, add the site to Categories as shown in the schema and return the updated category with the new site data using mongoose's populate method. But only the _id of site is being returned with the category data.
exports.addSite = async (req, res) => {
const {categoryId, siteUrl} = req.body;
console.log('categoryId, siteUrl', categoryId, siteUrl)
try {
let site = await Sites.findOne({url: siteUrl});
console.log('site', site)
if(site) {
return res.status(422).send(`${siteUrl} already exists.`)
}
site = await Sites.create({url: siteUrl, categoryId});
// site = {url: siteUrl, categoryId};
const category = await Categories.findOneAndUpdate({
_id: categoryId
}, {
$addToSet: {
sites: site
}
}, {
new: true
}).populate({
path: 'sites.site',
model: 'Sites'
})
console.log('category', category)
res.status(201).json(category);
} catch(error) {
console.error(error);
return res.status(500).send('Error adding category.')
}
}

Delete object from inner schema in mongoose?

How do I delete object from inner schema in mongoose?
I try to delete comments from the Holiday Schema, this is the holiday schema:
const holidaySchema = new mongoose.Schema(
{
comments: [commentSchema],
},
)
const Holiday = mongoose.model("Holiday", holidaySchema);
export default Holiday;
and this is the comments schema:
const commentSchema = new mongoose.Schema(
{
action: { type: String },
time: { type: String },
name: { type: String },
image: { type: String },
content: { type: String },
rating: { type: Number },
},
{
timestamps: true,
}
);
I try to delete a specific comment from the holidaySchema in this way:
holidayRouter.delete(
"/:id/comments/:commentId",
isAuth,
expressAsyncHandler(async (req, res) => {
const holiday = await Holiday.updateOne(
{ _id: req.params.id },
{ $pull: { comments: { _id: req.params.commentId } } }
);
if(holiday){
console.log(holiday);
}
})
);
the console:
and this is not working, do you know what I am doing wrong or what should I do?
thank you
Mongoose converts the object into json, and we can customize that json which is returned.
commentSchema.methods.toJSON = function(){
const commentSchema = this.toObject()
delete commentSchema.name
delete commentSchema.rating
return commentSchema
}
New the JSON which is returned will not have name and rating.

mongoose .populate() is not populating even with variable set to ObjectId

Here is my model for "product" schema:
const productSchema = new Schema({
productName: String,
productCategory: {
type: Schema.Types.ObjectId,
ref: "category",
},
productPrice: Number,
productImageUrl: String,
});
Here is the router for the GET method:
router.get("/", async (req, res) => {
try {
const products = await ProductModel.find().populate("category");
res.status(200).json({ erorr: false, products });
} catch (err) {
res.status(500).json({ error: true, err });
}
});
What I actually get is this:
"error": false,
"products": [
{
"_id": "6009f4bfd397734920c93ce8",
"productName": "Milk",
"productCategory": "6009d244332f2f22c40f90b4",
"productPrice": 8,
"productImageUrl":""
In Mongo Compass I can see that "productCategory" is set with ObjectId value.
Any ideas what am I doing wrong?
Thanks!
Try this one:
const mongoose = require('mongoose');
const Types = mongoose.Schema.Types;
const productSchema = new Schema({
productName: String,
productCategory: {
type: Types.ObjectId,
ref: "category",
},
productPrice: Number,
productImageUrl: String,
});
const products = await ProductModel.find({}).populate({path:"productCategory"});
you should put the key that has ref to populate like this:
const products = await ProductModel.find().populate("productCategory");

How to insert auto increment number in mongoose

Tried to insert auto increment number for serial number in mongodb using mongoose and nodejs but not working.Where i want to update my code to find solution.If anyone knows please help to find solution.
subs.model.js:
const mongoose = require('mongoose');
var subscriberSchema = new mongoose.Schema({
_id: {type: String, required: true},
email: {
type: String
}
}, {
versionKey: false,
collection: 'subscribers'
});
module.exports = mongoose.model('Subscribers', subscriberSchema);
data.controller.js:
module.exports.subscribeMail = (req, res, next) => {
var subscribeModel = mongoose.model("Subscribers");
var subscribemailid = req.query.email;
var subscribe = new subscribeModel({
email: subscribemailid
});
var entitySchema = mongoose.Schema({
testvalue: { type: String }
});
subscribe.save(function(error, docs) {
if (error) { console.log(error); } else {
console.log("subscribe mail id inserted");
console.log(docs)
res.json({ data: docs, success: true });
}
});
entitySchema.pre('save', function(next) {
var doc = this;
subscribe.findByIdAndUpdate({ _id: 'entityId' }, { $inc: { seq: 1 } }, function(error, counter) {
if (error)
return next(error);
doc.testvalue = counter.seq;
next();
});
});
};
If i use above code inserting data into mongodb like below:
_id:5f148f9264c33e389827e1fc
email:"test#gmail.com"
_id:6f148f9264c33e389827e1kc
email:"admin#gmail.com"
But i want to insert like this
_id:5f148f9264c33e389827e1fc
serialnumber:1
email:"test#gmail.com"
_id:6f148f9264c33e389827e1kc
serialnumber:2
email:"admin#gmail.com"
You can use this plugin: https://www.npmjs.com/package/mongoose-auto-increment
First you need to initialize it after creating Mongoose connection:
const connection = mongoose.createConnection("mongodb://localhost/myDatabase");
autoIncrement.initialize(connection);
Than in your subs.model.js file:
const mongoose = require('mongoose');
const autoIncrement = require('mongoose-auto-increment');
var subscriberSchema = new mongoose.Schema({
_id: {type: String, required: true},
email: {
type: String
}
}, {
versionKey: false,
collection: 'subscribers'
});
subscriberSchema.plugin(autoIncrement.plugin, {
model: 'Subscribers',
field: 'serialnumber'
});
module.exports = mongoose.model('Subscribers', subscriberSchema);

Mongoose Find subdocument in array

I have the following data in Robo3t
With this model:
const eleccionSchema = new mongoose.Schema({
e: [{
id: {
type: String,
required: true
},
l:[...]
}],
eleccion: {
type: Number,
required: true,
ref: 'Corte'
}
})
//? Create the model
const Eleccion = mongoose.model('Eleccion', eleccionSchema)
Right now I'm trying to fetch some data based on e.id like this
const eleccion = await Eleccion.findOne({'e.id':'A'})
But it's actually returning the whole array instead of just one
Fixed it with a projection: https://docs.mongodb.com/manual/reference/operator/projection/elemMatch/
const eleccion = await Eleccion.findOne({}, {
'e':
{ $elemMatch: { id: 'A' } }
})