I am trying to collect from a collection all contacts except those whose phone number is blacklisted. I have the following pipeline but I don't know how to reformat it so that instead of the hard-coded phone number, the mobile_phone field that is in the "contacts" collection is used.
db.getCollection("contactos").aggregate([
{
"$lookup": {
"from": "blacklist",
"localField": "mobile_phone",
"foreignField": "phone",
"as": "Blacklist"
}
},
{
"$match": {
"Blacklist.phone": {
"$ne": "+34000000000"
}
}
}
])
ISSUE
You want to filter documents from a collection called
contactos
, to obtain all the documents whose fieldmobile_phone
is not on the blacklist, the latter represented by documents from the collectionblacklist
that contain a field calledphone
.SOLUTION
One possible solution is to use a type aggregation stage
$lookup
that will allow us to get the documents from the collectionblacklist
whose fieldphone
matchesmobile_phone
the collection field ofcontactos
. For example:Then, to keep only those documents that do not have a match in the collection,
blacklist
we will use a stage$match
like the following:In this stage we have filtered the documents that do not have any correspondence with
blacklist
inspecting the size of the Array created by the$lookup
previous stage.However, this method is not as efficient as having the phone list beforehand.
For example, we could do the following:
Then we could already obtain the contacts that are not in said list using a simple query
find
on said collection like this:We have used the query operator
$nin
.Whenever you can avoid an aggregation process, avoid it, as it is more expensive in resources than the query of type
find
.I hope this helps you solve the problem.