damphat
damphat

Reputation: 18956

Understanding mongoose findOne().remove()

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

Answers (3)

dlsso
dlsso

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

damphat
damphat

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

Mattias Farnemyhr
Mattias Farnemyhr

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

Related Questions