0

Mongoose 6.6.1, MongoDB 6.0.1

Our team uses Mongo/Mongoose every day - but just the basics. I experiment with more advanced features, so I got a reputation as the local "Mongoose Guru" - but in the real world, I'm so not.

I clean up our log tables with a deleteMany for docs older than a week - no problem - simple filter.

But now I just want to keep the last 1000 docs & delete the rest - assumed it would be trivial, but how?

Mongoose 6.6.1 documents the 'deleteMany' methods for 2 Object types: Model & Query

MyModel.deleteMany([filter], [options]) calls the deleteMany method on the Model - MyModel.find().deleteMany([filter], [options]) calls it on the Query. Slightly different syntax

Since queries are chainable, my first assumption was that query.deleteMany() WITHOUT ANY ARGUMENTS would only delete the documents that were already filtered by the previous query. I played with both skip & limit - similar results.

MyModel.find() is a Query that matches all docs - so deleteMany removes them all

MyModel.find().limit(10) matches 10 docs.

Logically I assumed MyModel.find().limit(10).deleteMany(); should delete only those 10 BUT - that generates an error:

MongoServerError: The limit field in delete objects must be 0 or 1. Got 10

I can hack that but it's messy and I like elegant - am I missing something about deleteMany?

Just in case anyone is interested, the hack:

async function keepLast(myModel, n=10) {
  let edge = await myModel.findOne().sort({ _id: -1 }).skip(n);
  let res = await myModel.deleteMany({_id:{$lte:edge._id}});
  return res;
}

I'd like to think there was a better way that would also give more insight...

ChrisNY
  • 3,917
  • 4
  • 27
  • 31

0 Answers0