Reputation: 23
what I am trying to do , is to join two collections and then return elements whome names exist inside an array
these are the models
CarModel
id,
carAuthorizedDrivers:[String],
garageId:{type: Schema.ObjectId,ref:"garage"}
driversModel
id,
garageId:{type: Schema.ObjectId,ref:"garage"}
drivers:[{name:String,skill:String}]
this is the result of the join
{
"id":"1D99399379773",
"carAuthorizedDrivers":["DriverA","DriverB"],
"garageId":"010003",
"JoinDrivers":[drivers:[{"name":"DriverA","skill":"89"},{"name":"DriverB","skill":"77"},{"name":"DriverC","skill":"45"}]]
}
I want to restrict Joindrivers for the purpose of only showing drivers(name+skills) whome names belong to carAuthorizedDrivers , so I want joinDrivers to contain only the following :
{"name":"DriverA","skill":"89"},{"name":"DriverB","skill":"77"}
what i tried to do is the following :
join () {
return new Promise(function (resolve, reject) {
Car.aggregate([
{
$lookup: {
from: 'drivers', // collection name in db
localField: 'garage_id',
foreignField: 'garage_id',
as: 'joinDrivers'
}
},
{ $unwind: '$Joindrivers' },
{ $unwind: '$Joindrivers.drivers' },
{ $unwind: '$carAuthorizedDrivers' },
{ $match: { 'Joindrivers.drivers.name': { $in: 'carAuthorizedDrivers' } } }
]).exec((err, result) => {
if (err) {
reject(err)
}
resolve(result)
})
})
}
I get $in needs an array ERROR , but if I put an Array manually like this :
$match: { 'Joindrivers.drivers.name': { $in: ["DriverA","DriverB"] } }
$in works well and I get the result , how do I solve this issue ?
Upvotes: 0
Views: 3260
Reputation: 14287
To compare or match two document fields within an aggregation's $match
stage, you have to use an aggregation operator $in (not the query language operator $in). And, to use the aggregation operator in the $match
stage, you must use the $expr operator.
So, your match stage should be:
{ $match: { $expr: { $in: [ "$Joindrivers.drivers.name", "$carAuthorizedDrivers" ] } } }
The following code uses the output from the lookup stage to filter based on the provided condition:
db.collection.aggregate( [
{ $unwind: "$JoinDrivers" },
{ $addFields: {
"JoinDrivers.drivers": {
$filter: {
input: "$JoinDrivers.drivers", as: "driver",
cond: {
$in: [ "$$driver.name", "$carAuthorizedDrivers" ]
}
}
}
}},
] )
Upvotes: 5
Reputation: 59456
You mixed the Query operator $in with the Aggregation operator $in
Try this one:
{ $match: { $in: ["$Joindrivers.drivers.name", ["DriverA", "DriverB"] } }
Upvotes: 0