Mongoose - which update function will also generate id for new property? - mongodb

I have a subdocument inside a dosument and when I update my document, I want to generate ObjectId's. Both update and findByIdAndUpdate dont do that. I actually have to manually do that in my controller. Is there any way i can make it work?
const productSchema = new mongoose.Schema({
...
reports: [ReportSchema]
})
const ReportSchema = new mongoose.Schema({
...
info: String,
date: date
})
my controller:
updateProduct: async (req, res) => {
const product = await Product.update({id: id}, {
$push: {
report: {
info: info,
date: new Date(),
//_id: mongoose.Types.ObjectId() // only this works
},
}, $set: {isReport: true}}
)
res.status(200).send()
}
}

Related

How to create dynamic query in mongoose for update. i want to update multiple data(Not all) with the help of Id

If I'm doing this, the field which I don't want to update is showing undefined. Any solution? (Like generating dynamic query or something)
exports.updateStudentById = async (req, res) => {
try {
const updateAllField = {
first_name: req.body.first_name,
last_name: req.body.last_name,
field_of_study: req.body.field_of_study,
age: req.body.age,
};
const data = await student_master.updateOne(
{ _id: req.body._id },
{ $set: updateAllField }
);
res.json({ message: "Student Data Updated", data: data });
} catch (error) {
throw new Error(error);
}
};
You can go for a dynamic query creation .Example
const requestBody = {
first_name: "John",
last_name: "Cena",
field_of_study: ""
}
const query={};
if(requestBody.first_name){
query["first_name"]=requestBody.first_name
}
if(requestBody.last_name){
query["last_name"]=requestBody.last_name
}
Check for the fields that are present in req.body and create a dynamic query
and when updating using mongoose use this
const data = await student_master.updateOne(
{ _id: req.body._id },
{ $set: query }
);
In this way only those fields would be updated which are present in your req.body

How to update document with subdocument, or create new one if none are found

I'm trying to create a new subdocument object in an array when a user calls a command OR update the existing document based on their id. However, everything I've tried either gives me errors or it overrides the existing subdocument with the current user which is not what I want.
enter image description here
Basically I want to add another object in the array ( "1": Object ) that is a second user tracking whether they've used the command or not.
I can't remember all variations on code, but the current code I'm using:
const query = {
_id: guild.id,
members : [{
_id: user.id
}]
}
const update = {
members: {
_id: user.id,
bot: user.bot,
commandUsed: true
}
}
const options = {upsert: true, new: true}
await mongo().then(async () => {
console.log('Updating to...in use')
try {
// Find the document
await commandUsageSchema.findOneAndUpdate(query, update, options, function(error, result) {
if (!error) {
// If the document doesn't exist
if (!result) {
// Create it
result = new userSchema;
}
// Save the document
result.save(function(error) {
if (!error) {
// Do something with the document
} else {
throw error;
}
})
}
})
is creating a duplicate key error which is frustrating. Here is the layout of my schemas:
const mongoose = require('mongoose')
const reqString =
{
type: String,
required: true
}
const userSchema = mongoose.Schema({
_id: reqString,
bot: Boolean,
commandUsed: Boolean
}, {unique: true})
const commandUseSchema = mongoose.Schema({
_id: reqString,
members: [userSchema]
})
module.exports = mongoose.model('command-usage-checker', commandUseSchema)
I'm using mongoose and mongoDB (of course) with javascript and DiscordJS.

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.

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);

Pushing into nested subdocument arrays in mongoose

I have a rather complex db:
var bookSchema = mongoose.Schema({
content: {
page: [pageSchema]
},
//otherThings
});
//my book has pages
var pageSchema = mongoose.Schema(
{
comments: [commentSchema]
},
{_id: false}
);
//comments have replies.
var commentSchema = mongoose.Schema({
comment: String,
replies: [this]
});
I am trying to add a reply to a comment.
I have the ID of the comment to which I want to add the reply.
But how?
I tried:
Book.findOneAndUpdate(
{
'content.page.comments._id': ID
},
{
$push: {'content.page.$.comments.$.replies': myReply}
},
function (err) {
//...
}
)
But that is impossible because I cant use a positional($) more than once.
I'm trying to figure this one out for hours now.
Any advice?
Use simple way - commentsSchema
Comment.update({_id: ID}, {$push: {replies: myReply}}, function (err) {});
This will update comment model, and the book model will get updated too