Book Model
const BookSchema = new mongoose.Schema({
isbn: {
type: Number,
required: true,
unique: true,
},
name: {
type: String,
required: true,
},
});
module.exports = mongoose.model("Book", BookSchema );
Library Model
const LibrarySchema= new mongoose.Schema({
booksList: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Book",
},
],
name: {
type: String,
required: true,
},
});
module.exports = mongoose.model("Library", LibrarySchema);
deleteBook
router.delete("/:libraryID/book/:isbn", async (req, res) => {
try {
const book = await Book.findOne({
isbn: req.params.isbn,
});
await Library.findOneAndUpdate(
{_id: req.params.libraryID},
{$pull: {booksList: {_id: book._id}}},
{new: true},
function (error, data) {
console.log("Error: " + error);
if(!error) {
res.status(200).send({
success: true,
message: "Book removed successfully",
});
}
}
);
} catch (err) {
res.send({success: false, error: err.message});
}
});
I trying to pull a book with the object id from booksList array but nothing is working. I have tried almost every solution available on internet for this but nothing is working.
I always get this response but the book remains in the booksList array always.
{
success: true,
message: "Book removed successfully",
}
When you save a reference to another collection you are storing directly the _id. So your model has this example data:
[
{
"_id":1,
"booksList":[1,2,3,4],
"name":"name1"
}
]
Note how booksList is an array of numbers, not an array of objects {id: 1}.
So your query has to be without _id in the object _id: book._id. Something like this:
{$pull: {booksList: book._id}},
Check this example.
Related
so i'm creating CRUD with relation of two collections, then i got problem, i can't do push from first collection data to second collection. this is my code.
Schema
const CourseSchema = new Schema(
{
title: {
type: String,
required: true,
},
desc: String,
price: Number,
video: String,
category: String,
status: Number,
lessons: [
{
type: Schema.Types.ObjectId,
ref: "Lessons",
},
],
},
{
timestamps: true,
}
);
const course = mongoose.model("Courses", CourseSchema);
const LessonSchema = new Schema(
{
title: {
type: String,
required: true,
},
desc: String,
video: String,
status: Number,
},
{ timestamps: true }
);
const Lessons = mongoose.model("Lessons", LessonSchema);
code to do data push
Lessons.create(req.body)
.then((data) => {
res.status(200).send({
status: 200,
message: "Successfully Create Lessons",
data: data,
});
Course.findByIdAndUpdate(
courseId,
{ $push: { lessons: data._id } },
{ safe: true, upsert: true, new: true }
);
})
is there any solution for my problem? please help me, i'm just learning about one to many relation in nodejs using mongoose
You need a callback function to make it works.
Lessons.create(req.body)
.then((data) => {
res.status(200).send({
status: 200,
message: "Successfully Create Lessons",
data: data,
});
course.findByIdAndUpdate(
courseId,
{ $push: { lessons: data } },
{ safe: true, upsert: true, new: true },
function (err, newdoc) { // callback function
if (err) {
console.log(err);
} else {
console.log("completed");
}
}
);
})
Everything works fine but I have the above-mentioned error while deleting something with id in mongoose. I'm looking for a solution for last 3 days :( but nothing works for me.
// Delete a quote
router.delete("/delete/:id", async (req, res) => {
const result = await Post.findOneAndDelete({ _id: req.params.id }, (err, data) => {
if (err) {
res.status(500).json({
success: false,
message: "Sever error.",
});
} else {
res.status(200).json({
success: true,
message: "Post Deleted",
result,
});
}
});
res.json(result);
});
And my post schema:
const PostSchema = mongoose.Schema({
title: {
type: String,
required: true,
},
desc: {
type: String,
required: true,
},
createdAt: {
type: Date,
default: Date.now,
},
});
module.exports = mongoose.model("Posts", PostSchema);
I want to update my answer object inside answers array. I am using following schema
const mongoose = require("mongoose");
const { ObjectId } = mongoose.Schema;
const questionSchema = new mongoose.Schema(
{
postedBy: {
type: ObjectId,
required: true,
ref: "User",
},
question: {
type: String,
required: true,
},
photo: {
data: String,
required: false,
},
answers: [
{
userId: { type: ObjectId, ref: "User" },
answer: String,
},
],
questionType: {
data: String,
required: false,
},
},
{ timeStamps: true }
);
module.exports = mongoose.model("Question", questionSchema);
I am using updateOne method to update my answer in my db. Can anyone explain what is missing here. I am been trying to solve this since hours
exports.updateAnswer = (req, res) => {
const questionId = req.body.questionId;
const answerId = req.body.answerId;
Question.findOne({ _id: questionId }).exec((err, question) => {
if (err) {
res.status(400).json({
error: errorHandler(err),
});
return;
}
if (!question) {
res.status(400).json({
error: "question not found",
});
return;
}
});
Question.updateOne(
{ _id: answerId },
{
$set: {
"answers.$.answer": "This is update answer. My name is Ravi Dubey",
},
},
{ new: true },
(err, success) => {
if (err) {
res.status(400).json({
error: errorHandler(err),
});
}
res.json({
msg: "answer updated successfully",
success,
});
}
);
};
My result is coming successful but answer is not updating in db.
I am confused on Question.updateOne method.
Any help appreciated.
If you trying to query based on id of one of the documents in the answers array then instead of {_id: answerId} you need to provide {'answers._id': answerId}. And also if you need the updated document as result then you should use the findOneAndUpdate method.
Question.findOneAndUpdate(
{ "answers._id": answerId },
{ $set: { "answers.$.answer": "some answer" } },
{ new: true },
(err, data) => {
// handle response
}
);
Basically I'm trying to get the time and the entity changed in a particular model when ever the update method is called.
This is my model I want to keep track of:
const mongoose = require("mongoose");
const modelSchema = mongoose.Schema({
user: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
},
name: {
type: String,
required: true,
},
note1: String,
note2: String,
note3: String,
images: {
type: Array,
required: true
},
status: {
enum: ['draft', 'pending_quote', 'pendong_payment', 'in_production', 'in_repair', 'pemding_my_review', 'fulfilled'],
type: String,
default: "draft"
},
price: {
type: mongoose.Schema.Types.ObjectId,
ref: "Price",
}
}, {
timestamps: true,
})
module.exports = mongoose.model("Model", modelSchema)
And this is the method I call to update the status:
exports.updateModel = async (req, res) => {
try {
let id = req.params.id;
let response = await Model.findByIdAndUpdate(id, req.body, {
new: true
})
res.status(200).json({
status: "Success",
data: response
})
} catch (err) {
res.status(500).json({
error: err,
msg: "Something Went Wrong"
})
}
}
you can add a new field in your schema like:
logs:[{
entity: String,
timeStamp: Date
}]
Then updating it basing on your current code:
let id = req.params.id;
// I don't know whats in the req.body but assuming that it
// has the correct structure when passed from the front end
let response = await Model.findByIdAndUpdate(id,
{
$set:req.body,
$push:{logs:{entity:'your entity name here',timeStamp:new Date()}}
}, {
new: true
})
Here is my bid model.
const BidSchema = new Schema({
auctionKey: {
type: mongoose.Types.ObjectId,
ref: "Auction",
required: true
},
amount: { type: String, required: true },
userName: { type: String, required: true },
});
And, here is my Auction Model (Notice the relationships between these two models).
const AuctionSchema = new Schema({
title: { type: String, required: true },
startDate: { type: Date, required: true },
closeDate: { type: Date, required: true },
initialBidAmount: { type: Number, required: true },
bidIncrementAmount: { type: Number, required: true },
bids: [
{
type: mongoose.Types.ObjectId,
ref: 'Bid'
}
]
});
When user bids for any auction, I'm saving bid in bids collection and updating auctions collection using mongoose findOneAndUpdate.
const postBid = async (req, res, next) => {
const { auctionKey } = req.body;
const bid = new BidModel(req.body);
bid.save(error => {
if (error) {
res.status(500).json({ message: "Could not post bid." });
}
});
const aucById = await AuctionModel.findOneAndUpdate(
{ _id: auctionKey },
{ $push: { bids: bid } }
).exec((error: any, auction: IAuction) => {
if (error) {
res.status(500).json({ message: "Could not post bid." });
} else {
res.status(201).json({ bid });
}
});
};
For any reason if any of these two (save bid and findOneAndUpdate) throws any error I want nothing to be saved into database. I mean to say either they should save and update or nothing should be done on database.
I have tried using mongoose session and transaction but got this error.
MongoError: This MongoDB deployment does not support retryable writes. Please add retryWrites=false to your connection string.
Is there any way to work out in this scenario?
If I understand your problem right, you can just delete created document in:
.exec((error: any, auction: IAuction) => {
if (error) {
// here, by using .deleteOne()
res.status(500).json({ message: "Could not post bid." });
}
Or just change structure of your code, so only when two are successfully created, they will be saved and response will be sent.