Du kan göra en rå
fråga med aggregate()
som kan använda $lookup
operatör för att utföra "join" här:
$result = Booking::raw(function($collection) use($search, $start, $limit) {
return $collection->aggregate(array(
array( '$lookup' => array(
'from' => 'users',
'localField' => 'user',
'foreignField' => '_id',
'as' => 'user'
)),
array( '$unwind' => array(
'path' => '$user', 'preserveNullAndEmptyArrays' => True
)),
array( '$match' => array(
'$or' => array(
array( 'invoice_number' => array( '$regex' => $search ) ),
array( 'payment_type' => array( '$regex' => $search ) ),
array( 'txid' => array( '$regex' => $search ) ),
array( 'user.usrEmail' => array( '$regex' => $search ) )
)
)),
array( '$skip' => $start ),
array( '$limit' => $limit )
));
});
$lookup
kommer att returnera en "array" för målfältet som innehåller "ingen" eller fler matchande poster till det medföljande 'localField'
värde(n), där det antingen är singular eller en uppsättning värden. Vanligtvis använder vi ObjectId
här, speciellt när du länkar till 'foreignField'
som _id
.
Detta är bättre än något som kan göras på klientsidan, eftersom alla andra operationer skulle kräva att flera förfrågningar görs till databasen för varje samlingskälla. $lookup
gör detta i en enda begäran och ett svar.
Den enda riktiga noteringen är att eftersom detta är "separat" från ORM/ODM, måste du ange det faktiska "samlingsnamnet" och inte det för klassen eller modellen. Så jag antar bara "användare"
här, men du kanske måste anpassa det till vad din samling för Användare
egentligen heter.
Hur som helst, efter att du har "anslutit" data kan du $match
på "usrEmail"
egendom från de sammanfogade uppgifterna och inkludera i din fråga.
När det gäller den faktiska frågan, eftersom du i princip gör en $or
skick över data från båda samlingarna kan vi inte riktigt $match
tills "efter" sammanfogningen utförs.
Sedan finns det naturligtvis aggregeringsstadierna för $skip
och $limit
för din paginering också.