Reputation: 18956
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()
Upvotes: 12
Views: 8482
Reputation: 8111
I'm kind of a noob but wouldn't you need to put your remove in the callback because this is an asynchronous function? Try something like:
User.findOne({age: 30}, function(err, user){
user.remove()
})
Upvotes: 0
Reputation: 18956
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."
Upvotes: 10
Reputation: 4238
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().
Upvotes: 1