TLDR;
$pull is just an update. So the pulling happens only on the documents returned by the query part of update
Some background first. The $pull
operator in MongoDB is used in conjunction with the update
command to remove (or pull out) elements from an array.
The syntax for an update
command is
db.collection.update(
{ /* find query */ },
{ /* new value */ }
);
Copied from the official documentation :
{ flags: ['vme', 'de', 'pse', 'tsc', 'msr', 'pae', 'mce' ] }
The following operation will remove the msr value from the flags array:
db.cpuinfo.update( { flags: 'msr' }, { $pull: { flags: 'msr' } } )
Personally, I had a hard time understanding the necessity of the first part of the update
command in this case. If the values equallying ‘msr’ are going to be pulled for the key equallying ‘flags’, then why repeat the same in the query part?
Although the documentation is not incorrect, the oversimplified example makes it deceptive. The $pull
operator is does not come into play, till the query part returns any documents. In other words, keep in mind that this is just an extension to update
. So, don’t think about the pull
till the query part is satisfied by at least one document in the collection.
For e.g.,
db.students.insert({
name: 'Bob',
grades: ['low', 'high']
});
db.students.insert({
name: 'Mom',
grades: ['low', 'average']
});
Now, although the $pull
part in the following query would seem to satisfy both the documents, the grade ‘low’ will be removed only from ‘Mom’.
db.students.update(
{ name: 'Mom' },
{ $pull: {grades: 'low'} }
);