This question already has answers here:
Mongoose: findOneAndUpdate doesn't return updated document
(16 answers)
Closed 3 years ago.
I am working on node js app using express.js and mongodb with mongoose module to handle the database.
in one case I need to update a user property languages using findOneAndUpdate method. this property is an array of objects should looks like [{"language":"Ar","level":4}]
when I update it using the following nodejs code :
User.findOneAndUpdate({_id:mongoose.Types.ObjectId(req.body.id)},
{$set:{[req.body.key]:req.body[req.body.key]}},(err,doc)=>{
console.log(req.body) // {id:5d1619fa7c11fa102210ef86,"languages":[{"language":"Ar","level":4}],key:"languages"}
if (!err) {
res.json(200,doc);
}else{
res.json(500,{error:err});
}
})
I get the following results
but when I try same thing from the mongo shell
db.users.findOneAndUpdate({"_id" : ObjectId("5d1619fa7c11fa102210ef86")},{ '$set': {"languages":[{"language":"Ar","level":4}]} })
I get the correct result
which is the correct expected results.
any idea why the nodejs snippet not working properly.
thanks in advance.
I think you are not getting the updated result back after update has successfully run. you need to pass new : true in your update query as the third argument.
By default mongodb returns the old document after the update, but you can specify to return the updated document in the query.
Try this :
User.findOneAndUpdate({_id:mongoose.Types.ObjectId(req.body.id)},
{$set:{[req.body.key]:req.body[req.body.key]},{new:true},(err,doc)=>{
...
//doc will be updated doc here
})
Related
I'm currently trying to return the document I just added to a collection to display it in real time on my homepage.
I followed a solution I found here: link to 2018 solution. But this solution doesn't seem to work for the latest node.js and MongoDb versions.
I'm essentially trying to do the same thing the person in that post was trying to do but I get the following error:
res.json (info.ops[0]);
TypeError: Cannot read property '0' of undefined
Here's my code for reference:
app.post('create-item', (req, res) => {
dB.collection('items').insertOne({text: req.body.text}, (err, info) => {
res.json(info.ops[0]);});});
When we use insertOne with the Nodejs driver 4 (the latest) we get a response like
{"acknowledged" : true, "insertedId" : #object[ObjectId 61105622b633ecabf3706782]}
Save the document to a variable before inserting it.
If the document had _id, check if it was inserted and get the document from the variable.
If the document didn't had _id, check if it was inserted and get the _id also from the response, and add that _id to the document you have in the variable.
Maybe i am missing something but the above is simple to do, if this is what you need.
I wanted to update the field data only ,but my code it adding an object each time i am calling update api.I have gone through many sites and found out updateOne is the method but couldnt end up undersatnding how to implement here.I am quite new to node so any help would be appreciated.
const update=(req,res)=>{
console.log(req);
models.detailsSchema.findByIdAndUpdate(req.body.vehicleId,req.body.data,{new:true}).then((msg,err)=>{
if(err)
res.status(400).json({err})
res.status(200).json({
"resCode":"0000",
"resStatus":"Success",
"resMsg":msg
})
});
}
Looks like you're using Mongoose connected to a MongoDB instance? If that's the case, Schema.findByIdAndUpdate works on the primary key or ObjectId of the record you're trying to update. To make this code work, if my assumptions are correct, change to this:
models.detailsSchema.findByIdAndUpdate(req.body._id, req.body.data, { new:true })
Of course, you're going to want to put in some check to make sure _id is defined if this is a create/update route.
I am trying to use the new unstable version of mongoose >4.0.0 to validate update queries.
say that i want to update a schema using the following query
schema.update({_id:'blah'},{a:'blah'},function(err){
//do your thing
})
so lets say i have the following schema,
var schema = new Schema({
a:{type:String}
});
schema.pre('update',function(next){
var findQuery=this._conditions; // gives {_id:'blah'}
// how do i get {a:'blah'}????
next();
});
how do i get the update query of {set:{a:'blah'}} in the pre middleware so i can do some checks before executing the update?
alternatively i know that the update query can be accessed in the post middleware, in
schema.post('update',function(){
var findQuery=this._conditions; // gives {_id:'blah'}
var updateQuery=this._update; //gives {$set:{a:'blah'}}
next();
});
but thats too late, i need this in the pre middleware to check before actually updating the db.
i tried looking through the 'this' object of the pre middleware but cannot find the updateQuery object anywhere and this._update is undefined in the pre middleware.
Is there a way to do this?
thanks
In case you're still looking for a solution that works on array operations, it looks like in newer versions of mongoose (at least 4.0.7+), this._update is defined in the pre-middleware.
I found a work around through this particular example, however it doesnt quite solve my actual problem. what you can do in mongoose version ~4.0.0 is to let the pre middleware specify to go through the model validation on update.
schema.pre('update',function(next){
this.options.runValidators = true; // make sure any changes adhere to schema
})
basically, you can then specify the validators inside the schema
var schema = new Schema({
a:{
type:String,
validate:[...] //the validation you want to run
}
});
you can choose to skip the validation on a normal save operation by using the this.isNew check inside validation functions.
this code will run validate:[...] on any $set and $unset to a in your update query.
however, it doesn't work on array operations like $push or $addToSet for some reason. so if your updating an array, it won't run the validation code at all! hence it doesn't solve the actual problem im faced with. but it can work with the example provided for anyone that comes across this particular problem
This question already has answers here:
Node.js - Mongoose - Check if a collection exists
(4 answers)
Closed 8 years ago.
I am new to mongo Db and need to see if schema is already been created or not. I am using mongoose and node.js. If its not created i need to somehow run the creation script for once or else proceed with other stuff.
TIA
Assuming that by schema you mean that you want a check if the collection is already created in mongoDB, you should check this question here that explains the solution.
Quoting it:
Assuming you have a Mongoose Connection object named conn that's been opened using mongoose.createConnection, you can access the native mongo Db object via conn.db. From there you can call collectionNames which should provide what you're looking for:
conn.db.collectionNames(function (err, names) {
// names contains an array of objects that contain the collection names
});
You can also pass a collection name as a parameter to
collectionNames to filter the results to just what you're looking for.
I have a document:
{
"_id":ObjectId("someID")
"email":"john#example.com"
}
I would like to retrieve "john#example.com" so that I can pass this value to the browser.
How do I do that?
I saw these SO posts, but I don't understand the solution at all:
How to get string value inside a Mongodb document?
How to get value from a MongoDB document