As you know, in mongoose
, we can remove all users with age 30 like this:
User.find({age: 30}).remove(callback);
Now, replace find()
with findOne()
, and I think it should remove only 1 user:
User.findOne({age: 30}).remove(callback);
oh, not as I expected, the code above also remove ALL instead of ONE
So, why findOne().remove()
remove ALL instead of ONE? Is that a bug or a feature and why?
Thanks in advance!
P/S: I know findOneAndRemove()
would remove one user for me, but in this question I want to understand findOne().remove()
Mongoose | findOne() Function The findOne() function is used to find one document according to the condition. If multiple documents match the condition, then it returns the first document satisfying the condition.
Mongoose findOne query returns a query object, not a document. You can either use a callback as the solution suggests or as of v4+ findOne returns a thenable so you can use . then or await/async to retrieve the document.
There is currently no method called deleteById() in mongoose. However, there is the deleteOne() method with takes a parameter, filter , which indicates which document to delete. Simply pass the _id as the filter and the document will be deleted.
Mongoose | deleteMany() Function The deleteMany() function is used to delete all of the documents that match conditions from the collection. This function behaves like the remove() function but it deletes all documents that match conditions regardless of the single option.
I have reported this question to mongoose team, and got a reply:
https://github.com/LearnBoost/mongoose/issues/1851#issuecomment-31355346
Here's the message from aheckmann
"that's a good catch. findOne just sets the command name to run, remove() changes it back to a rice command but no limit was ever set. We should probably change that in 3.9 so that findOne sets the limit as well."
Both find
and findOne
returns mongoose Query objects which only contains information about the model and the specified query. It's not taking into account findOne
which is applied first in the callback. What you expect to happen is to have options be set like this User.findOne({age: 30}, null, {limit: 1}).remove()
as this would only remove one and you could argue that this is a bug, but that depends on the usage. Like you have already pointed out, the right way to go is to use findOneAndRemove().
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With