user3803096
user3803096

Reputation: 901

Update And Return Document In Mongodb

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?

Upvotes: 85

Views: 119998

Answers (7)

Fazeel Mehar
Fazeel Mehar

Reputation: 61

With Single Field

 var filter = Builders<MongoDbModel>.Filter.Eq(u => u.Id, model.Id);
 var update = Builders<MongoDbModel>.Update.Set(u => u.Value, model.NewValue);

await collection.UpdateOneAsync(filter, update);

With Multiple Fields

 var filter = Builders< MongoDbModel>.Filter.Eq(u => u.Id, model.Id);
 var update = Builders< MongoDbModel>.Update.Set(u => u.Field1, model.NewValue1)
                                            .Set(u => u.Field2, model.NewValue2);


 await collection.UpdateOneAsync(filter, update);

Upvotes: 0

Blagovest Georgiev
Blagovest Georgiev

Reputation: 111

A bit late for the party but here's a simple 2022 solution to your question. I'm using NestJS for this app

const updatedPainting: Partial<IGallery> = {
    imageAltTxt: updateGalleryDto.imageAltTxt,
    name: updateGalleryDto.name,
    dateCreated: updateGalleryDto.dateCreated,
    size: updateGalleryDto.size,
    description: updateGalleryDto.description,
    isFeatured: updateGalleryDto.isFeatured || false,
  };
  return await this.galleryModel.findOneAndUpdate(
    { _id },
    { $set: { imageUrl, ...updatedPainting } },
    { returnDocument: 'after' },
  );

Upvotes: 4

voldi muyumba
voldi muyumba

Reputation: 81

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)

Upvotes: 3

Jonathan Lonowski
Jonathan Lonowski

Reputation: 123453

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.

Upvotes: 130

milosnkb
milosnkb

Reputation: 1591

The solution is to set: {returnOriginal: false}.

collection.findOneAndUpdate(
        whereObj,
        updateObj,
        {returnOriginal: false});

Upvotes: 16

Venkat Rangan
Venkat Rangan

Reputation: 385

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.

Upvotes: -6

mido
mido

Reputation: 25034

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()
    })
}

Upvotes: 6

Related Questions