Update And Return Document In Mongodb
node.jsMongodbnode.js Problem Overview
I want to get updated documents. This is my original code and it successfully updates but doesn't return the document.
collection.update({ "code": req.body.code },{$set: req.body.updatedFields}, function(err, results) {
res.send({error: err, affected: results});
db.close();
});
I used the toArray
function, but this gave the error "Cannot use a writeConcern without a provided callback":
collection.update({ "code": req.body.code },{$set: req.body.updatedFields}).toArray( function(err, results) {
res.send({error: err, affected: results});
db.close();
});
Any ideas?
node.js Solutions
Solution 1 - node.js
collection.update()
will only report the number of documents that were affected to its own callback.
To retrieve the documents while modifying, you can use collection.findOneAndUpdate()
instead (formerly .findAndModify()
).
collection.findOneAndUpdate(
{ "code": req.body.code },
{ $set: req.body.updatedFields },
{ returnOriginal: false },
function (err, documents) {
res.send({ error: err, affected: documents });
db.close();
}
);
The returnOriginal
option (or new
with Mongoose) lets you specify which version of a found document (original [default] or updated) is passed to the callback.
returnOriginal
was deprecated in version 3.6
. Use returnDocument: "before" | "after"
for version 3.6
and later.
> Disclaimer: This answer currently refers to the Node.js Driver as of version 3.6. As new versions are released, check their documentation for possibly new deprecation warnings and recommended alternatives.
Solution 2 - node.js
The solution is to set: {returnOriginal: false}.
collection.findOneAndUpdate(
whereObj,
updateObj,
{returnOriginal: false});
Solution 3 - node.js
Could not find any way to update many and return the modified records in docs, so I made a workaround.
At least one fault that I can find with below method is, you would not be able to tell if document is modified or already had the value that you are using:
function findAndUpdateMany(filter, updateOptions) {
return collection.find(filter).project({_id: 1}).toArray()
.then(function(matchingIds) {
filter = {_id: {$in: matchingIds}}
return collection.updateMany(filter, updateOptions)
}).then(function() {
return collection.find(filter).toArray()
})
}
Solution 4 - node.js
to get the updated doc when performing an update operation on one doc, use findOneAndUpdate() and in the options object, set returnDocument property to 'after'
let options = {returnDocument: 'after'}
const upadatedDoc = collection.findOneAndUpdate({'your query'},{'your update'}, options)
Solution 5 - node.js
In case you are using mongoose, returnOriginal: false
did NOT work for me at v5.11.10
,
but new: true
worked,
const filter = { name: 'Jean-Luc Picard' };
const update = { age: 59 };
let doc = await Character.findOneAndUpdate(filter, update, {
new: true
});
doc.name; // 'Jean-Luc Picard'
doc.age; // 59
Solution 6 - node.js
Checkout the WriteResult object:
http://docs.mongodb.org/manual/reference/method/db.collection.update/#writeresults-update
WriteResult result = collection.update({ "code": req.body.code },{$set: req.body.updatedFields}, function(err, results) {
res.send({error: err, affected: results});
db.close();
});
result should have something like:
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
If you want the updated results, do another query with the primary key.