Home > Net >  How to update many documents on mongo and return that updated document?
How to update many documents on mongo and return that updated document?

Time:11-03

How can I update many documents on mongoose and return those updated documents so I then I can pass the updated docs to a different service on my code? This is seems like something simple to do but I'm getting confused on my head on how to implement it

In my current code I just update the documents on batch with updateMany, but as the mongo documentation says the writeConcern returned is just the # of docs updated {n: 0 } not the actual documents.

Current Code:

const checkAndUpdateSubscription = () => {
  const filter = {
    "payments.0.stripeSubscriptionEndDate": { $lte: today },
    hasPaid: true,
  };
  const update = { $set: { hasPaid: false, isSubscriptionNew: 0 } };
  const options = { new: true, useFindAndModify: false };

  return new Promise((resolve, reject) => {
    ModelModel.updateMany(filter, update, options)
      .then((response) => {
        console.log('response inside checkAndUpdateSubscription', response)
        resolve(response);
      })
      .catch((error) => {
        reject(error);
      });
  });
};

I would like to change it to something similar to my pseudo code below.

What I would like to do:

const checkAndUpdateSubscription = () => {
  const filter = {
    "payments.0.stripeSubscriptionEndDate": { $lte: today },
    hasPaid: true,
  };
  const update = { $set: { hasPaid: false, isSubscriptionNew: 0 } };
  const options = { new: true, useFindAndModify: false };

  return new Promise((resolve, reject) => {
    // 1. ModelModel.find where stripeSubscriptionEndDate $lte than today ..etc
    // 2. Update the document(s) 
    // 3. Return the updated document(s)
    (//4.) .then(updatedModel => sendUpdateModelToOutsideService(updatedModel))

  });
};

I don't know if this is necessary in the context of this question but the checkAndUpdateSubscription method is a function that runs every 1min in my db for all my users (# ~thousands)

CodePudding user response:

You can do those as alternative solutions
(maybe there is simpler way, but those will work i think)

Find the ids

  • find to get those ids
    ids = find(your_filter,project_keep_id_only), and then make ids=[_id1, _id2 ...] an array of the ids
  • update with filter _id $in ids
    update({"_id" : {"$in" : ids}},your_update_set_etc)
  • find to get the updated documents
    docs=find({"_id" : {"$in" : ids}})

*if ids are not too many it will be fine i think

Mark the updated with extra field

  • on update set one extra field with the update_id
  • after the update, do a find based on that update_id, to get the documents
  • and if you want your remove that extra field after

If this run parallel, this extra field could be an array, with many update_ids, that you remove them after you get those documents back.

  • Related