Je kunt een raw
. doen query met aggregate()
die de $lookup
kan gebruiken
operator om de "join" hier uit te voeren:
$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 )
));
});
De $lookup
retourneert een "array" voor het doelveld met "none" of meer overeenkomende items naar het opgegeven 'localField'
waarde(n), waarbij dat een enkelvoud is of een reeks waarden. Meestal gebruiken we ObjectId
hier, vooral bij het linken naar de 'foreignField'
als _id
.
Dit is beter dan alles wat aan de clientzijde kan worden gedaan, omdat voor elke andere bewerking meerdere query's naar de database voor elke verzamelingsbron moeten worden gemaakt. $lookup
doet dit in een enkel verzoek en antwoord.
De enige echte opmerking is dat, omdat dit "apart" is van de ORM/ODM, u de werkelijke "verzamelingsnaam" moet specificeren en niet die van de klasse of het model. Dus ik veronderstel gewoon "users"
hier, maar misschien moet u dat aanpassen aan uw verzameling voor Users
heet eigenlijk.
Hoe dan ook, nadat je de "samengevoegde" gegevens hebt, kun je $match
op de "usrEmail"
eigenschap van de samengevoegde gegevens en neem deze op in uw zoekopdracht.
Wat betreft de eigenlijke vraag, aangezien je in feite een $or
. doet voorwaarde voor gegevens uit beide verzamelingen kunnen we niet echt $match
totdat "na" de samenvoeging is uitgevoerd.
Dan zijn er natuurlijk de aggregatiefasen voor $skip
en $limit
ook voor uw paginering.