I’m new to mongoDB, I am trying to achieve the following SQL query on it. but could not find anything useful so far. can anyone tell equivalent mongoose query
JavaScript
x
11
11
1
select * from interviews
2
inner join candidate on interviews.clientId = candidate._id
3
inner join billing on appointment._id = billing.appointmentId
4
where ('
5
interviews.status= "upcoming",
6
interviews.startTime= "2017-01-01",
7
candidate.clientAgeGroup= "adult",
8
candidate.candidatetatus= "new",
9
billing.paymentStatus= "paid"
10
')
11
what I got so far is following
JavaScript
1
8
1
const [result, err] = await of(Interview.find({ filterQuery }).limit(perPage)
2
.skip(perPage * page)
3
.sort({
4
startTime: 'asc'
5
})
6
.populate([{ path: 'candidateId', model: 'Candidate', select: 'firstName status avatar' },
7
{ path: 'billingId', model: 'Billing', select: "status" }]));
8
UPDATE
I have following name and export scheme
JavaScript
1
5
1
//interview.model.js => mongodb show name as interview
2
module.exports = mongoose.model('Interview', interviewSchema);
3
//candidate.model.js => mongodb show name as candidate
4
module.exports = mongoose.model('Candidate', candidateSchema);
5
Advertisement
Answer
You can use filter out objects included in resulting array using match
but in the case if it couldn’t find any, it would still return a null value. So in comparison this works similar to sql left join.
JavaScript
1
8
1
const [result, err] = await of(Interview.find({ filterQuery }).limit(perPage)
2
.skip(perPage * page)
3
.sort({
4
startTime: 'asc'
5
})
6
.populate([{ path: 'candidateId', model: 'Candidate', select: 'firstName status avatar', match: {clientAgeGroup: "adult", candidatetatus: "new"} },
7
{ path: 'billingId', model: 'Billing', select: "status", match: {paymentStatus: "paid"} }]));
8
Also see https://mongoosejs.com/docs/populate.html#query-conditions
If you need strictly a inner join then you can use mongodb aggregate pipeline.
JavaScript
1
37
37
1
Interview.aggregate([
2
{
3
"$match": {
4
status: "upcoming",
5
startTime: "2017-01-01",
6
}
7
},
8
{
9
'$lookup': {
10
'from': 'candidates', // this should be your collection name for candidates.
11
'localField': 'candidateId', // there should be an attribute named candidateId in interview model that refer to candidate collection
12
'foreignField': '_id',
13
'as': 'candidates'
14
}
15
}, {
16
'$match': {
17
'candidates.clientAgeGroup': "adult",
18
'candidates.candidatetatus': "new"
19
}
20
},
21
{
22
'$lookup': {
23
'from': 'billing', // this should be your collection name for billing.
24
'localField': 'billingId', // there should be an attribute named billingId in interview model that refer to billing collection
25
'foreignField': '_id',
26
'as': 'billing'
27
}
28
}, {
29
'$match': {
30
'billing.paymentStatus': "paid"
31
}
32
},
33
{ "$sort": { startTime: 1 } },
34
{ "$limit": perPage },
35
{ "$skip": perPage * page }
36
])
37