1

I am looking to a way to FindAndModify not more than 5 documents in MongoDB.

This is collection for queue which will be processed from multiple workers, so I want to put it into single query.

While I cannot control amount of updates in UpdateOptions parameter, is it possible to limit number of rows which will be found in filterDefinition?

st78
  • 8,028
  • 11
  • 49
  • 68

1 Answers1

3

Problem 1: findAndModify() can only update a single document at a time, as per the documentation. This is an inherent limit in MongoDB's implementation.

Problem 2: There is no way to update a specific number of arbitrary documents with a simple update() query of any kind. You can update one or all depending on the boolean value of your multi option, but that's it.

If you want to update up to 5 documents at a time, you're going to have to retrieve these documents first then update them, or update them individually in a foreach() call. Either way, you'll either be using something like:

db.collection.update(
    {_id: {$in: [ doc1._id, doc2._id, ... ]}},
    { ... },
    {multi: true}
);

Or you'll be using something like:

db.collection.find({ ... }).limit(5).forEach(function(doc) {
    //do something to doc
    db.collection.update({_id: doc._id}, doc);
});

Whichever approach you choose to take, it's going to be a workaround. Again, this is an inherent limitation.

B. Fleming
  • 7,170
  • 1
  • 18
  • 36
  • Thanks, but this is not perfect. What if other worker already handled doc2 in between? E.g. operation is send email for your order than I will have multiple emails sent to same customer. – st78 Feb 15 '18 at 20:12
  • FYI - I am inclined to use 5 individual calls of findOneAndUpdate for my specific pattern as most reliable solution – st78 Feb 15 '18 at 20:14
  • Unfortunately that's just a problem you're going to encounter when dealing with MongoDB and asynchronous updates. There is no existing solution for batch updates of a limited number of documents. Your sequential `findOneAndUpdate()` calls solution is probably ideal for your use case (the only reason I didn't provide that as a solution is because it doesn't fit the "single query" requested). Otherwise, you'll need to find some way to enforce synchronization at the application level. Good luck with whatever solution you elect to go with! – B. Fleming Feb 15 '18 at 20:20
  • This is an excellent answer. It has probably saved me hours of trying to do the impossible. – Phil Nov 13 '22 at 23:31