You can use the following pipeline using $lookup
:
async isCaseBelongToRiderCompany(userId, caseId): Promise<boolean> {
const employeeIdFromUser = await this.connection.db
.collection('users-permissions_user')
.aggregate([
{
$match: {
_id: new mongo.ObjectID(userId),
},
},
{
$lookup: {
from: 'cases',
let: { employer: '$employer', caseId: caseId },
pipeline: [
{
$match: {
$expr: {
$and: [
{
$eq: [
'$_id',
'$$caseId',
],
},
{
$eq: [
'$provider',
'$$employer',
],
},
],
},
},
},
],
as: 'cases',
},
},
{
$match: {
'cases.0': { $exists: true },
},
},
]).toArray();
return employeeIdFromUser.length > 0;
}
I personally do not recommend it, the aggregation pipeline has some overhead, combined with the fact that this $lookup
syntax does not utilize indexes if you're on Mongo version lesser than 5 makes this less efficient by a mile.
The two separate calls is in fact the best approach as they are both indexed and very lean, you can just make the code a little cleaner:
async isCaseBelongToRiderCompany(userId, caseId): Promise<boolean> {
const employeeIdFromCase = await this.connection.db
.collection('cases')
.findOne({
_id: new mongo.ObjectID(caseId)
})
const employeeIdFromUser = await this.connection.db
.collection('users-permissions_user')
.findOne({
_id: new mongo.ObjectID(userId)
})
return employeeIdFromCase?.provider?.toString() === employeeIdFromUser?.employer?.toString()
}
Additionally you can execute both promises at the same time using Promise.all
, like so:
async isCaseBelongToRiderCompany(userId, caseId): Promise<boolean> {
const [employeeIdFromCase, employeeIdFromUser] = await Promise.all([
this.connection.db
.collection('cases')
.findOne({
_id: new mongo.ObjectID(caseId)
}),
this.connection.db
.collection('users-permissions_user')
.findOne({
_id: new mongo.ObjectID(userId)
})
])
return employeeIdFromCase?.provider?.toString() === employeeIdFromUser?.employer?.toString()
}