Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongoose select fields to return from findOneAndUpdate

Using Mongoose in Nodejs you can return some fields using find. eg.

User.findOne({_id:'132324'}, {first_name:1, last_name:1}).exec...

but I can't seem to figure out how to return certain fields using findOneAndUpdate.

User.findOneAndUpdate({_id:'132324'}, {$set : {..bla bla}}, {first_name:1, last_name:1}).exec....

Has anyone achieved this before? I can't find it in the documentation.

like image 273
Emad Said Avatar asked May 22 '17 03:05

Emad Said


People also ask

What does findOneAndUpdate return mongoose?

By default, findOneAndUpdate() returns the document as it was before update was applied. You should set the new option to true to return the document after update was applied.

What is the difference between updateOne and findOneAndUpdate?

findOneAndUpdate returns a document whereas updateOne does not (it just returns the _id if it has created a new document).

What does findByIdAndUpdate return mongoose?

Mongoose | findByIdAndUpdate() Function The findByIdAndUpdate() function is used to find a matching document, updates it according to the update arg, passing any options, and returns the found document (if any) to the callback.

Does findOneAndUpdate create new?

When true , findOneAndUpdate() either: Creates a new document if no documents match the filter . For more details see upsert behavior.


3 Answers

From the manual, the options argument needs a "fields" key in it since there are other details such as "upsert" and "new" where this applies. In your case you also want the "new" option:

User.findOneAndUpdate(
  { "_id": "132324" },
  { "$set": { "hair_color": "yellow" } },
  {
   "fields": { "first_name":1, "last_name": 1 },
   "new": true 
  }
).exec(...)

Alternately you may use .select()

User.select({ "first_name": 1, "last_name": 1 }).findOneAndUpdate(
  { "_id": "132324" },
  { "$set": { "hair_color": "yellow" } },
  { "new": true }
).exec(...)

Noting that without "new": true the document returned is in the state before the modification of the update was processed. Some times this is what you mean, but most of the time you really want the modified document.

like image 150
Neil Lunn Avatar answered Oct 16 '22 22:10

Neil Lunn


It seems the syntax for findByIdAndUpdate has changed a little.

Its takes the form of Model.findByIdAndUpdate(query, update, options, (optional callback))

According to the docs, to specify which fields are returned you have to specify them in the options parameter. so, using the above example it would be:

User.findOneAndUpdate(
  {id},  //query
  { $set: { "fieldToBeChanged": "update" } },  //update
  {new:true, select: "fieldIWant anotherFieldIWant"}, //options
})

The new:true options is not necessary. If omitted mongoose defaults to returning the document before the updates were applied. Set to true and it will return the document after the updates have been made.

like image 34
Neil Avatar answered Oct 16 '22 21:10

Neil


We can exclude any field while using mongoose update function findByIdAndUpdate with the help of select function,please have a look at the following code it will exclude password and __v from the Update response

User.findByIdAndUpdate({ _id: req.userData.UserId },req.body,{new: true}).select({Password: 0, __v: 0 })
    .exec()
    .then(result => {})
like image 1
INDRASEN KUMAR Avatar answered Oct 16 '22 22:10

INDRASEN KUMAR