44

I have a very simple case. I want to update my collection every midnight. Im using node-schedule:

schedule.scheduleJob('0 0 * * *', () => {
   Users.updateMany();
});

All I want to do, is to loop over every document in my collection (Users) and then if User.created is false, I want to turn it into true.

In javascript it would be:

for (let user in Users) {
   if (user.created === false) {
      user.created = true;
   }
} 

How to do it in mongoose? Thanks!

Edit: The story is very simple, I just want to iterate over every element in my db using mongoose and if iterated element has field "created" === false, change it to true.

Patrickkx
  • 1,740
  • 7
  • 31
  • 60

2 Answers2

86

You can use updateMany() methods of mongodb to update multiple document

Simple query is like this

db.collection.updateMany(filter, update, options)

For more doc of uppdateMany read here

As per your requirement the update code will be like this:

User.updateMany({"created": false}, {"$set":{"created": true}});

here you need to use $set because you just want to change created from true to false. For ref. If you want to change entire doc then you don't need to use $set

abernier
  • 27,030
  • 20
  • 83
  • 114
Harsh Patel
  • 6,334
  • 10
  • 40
  • 73
  • Thanks! What If I want to add some condition? For all those entries which "created" is false? Something like: `({ created: false }, () => { if (selected.date > 100) { do something } })`? – Patrickkx Mar 10 '19 at 23:02
  • For that you need to use [aggregation](https://docs.mongodb.com/manual/reference/operator/query/gt/) – Harsh Patel Mar 11 '19 at 08:32
33

You first need a query to find the documents you want to update. This is simply:

{"created": false}

Then you need an update query to tell mongo how to update those documents:

{"$set":{"created": true}}

You need to use the $set operator to specify which fields to change, otherwise it will overwrite the entire document. Finally you can combine these components into a single mongo call with an additional parameter to tell mongo we want to modify multiple documents:

User.update({"created": false}, {"$set":{"created": true}}, {"multi": true}, (err, writeResult) => {});

Mongoose tries to closely replicate the mongo API so all this information can be found solely within MongoDB's documentation: https://docs.mongodb.com/manual/reference/method/db.collection.update/

jakedipity
  • 890
  • 8
  • 19
  • Thanks, but I need solution in mongoose – Patrickkx Mar 05 '19 at 17:11
  • @Patrickkx, the answer is mongoose. I've slightly edited it to reflect your code snippets – jakedipity Mar 07 '19 at 03:24
  • What is `writeResult`? What if I only want to add "created" : true only for selected entries? Like only for these, where `date > 100`? How to add a condition? – Patrickkx Mar 10 '19 at 23:03
  • @Patrickkx you can write anything in place of `writeResult` like doc ..`doc) => { if (doc) return res.send(doc);` . For date you need to put in `if` condition. – NoobCoder Jun 12 '19 at 11:23
  • await User.updateMany({ created: false }, {"$set":{"created": true}} ). Just this will work! You can use async/await if you want to wait for either success or error. With mongoose updateMany() you do not need the {multi:true} in the options. I used this before to update multiple docs – KJ Ang May 26 '21 at 15:28