Můžete udělat raw
dotaz pomocí aggregate()
který může používat $lookup
operátora k provedení "připojení" zde:
$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
vrátí "pole" pro cílové pole obsahující "none" nebo více odpovídajících položek do zadaného 'localField'
value(s), kde je buď singulární, nebo pole hodnot. Obvykle používáme ObjectId
zde, zejména při odkazování na 'foreignField'
jako _id
.
To je lepší než cokoli, co lze provést na straně klienta, protože jakákoli jiná operace by vyžadovala provedení více dotazů do databáze pro každý zdroj kolekce. $lookup
udělá to v jediném požadavku a odpovědi.
Jediná skutečná poznámka je, že protože je to „oddělené“ od ORM/ODM, musíte zadat skutečný „název kolekce“ a ne název třídy nebo modelu. Takže jen předpokládám "uživatelé"
zde, ale možná to budete muset upravit podle toho, co vaše sbírka pro Uživatele
se ve skutečnosti nazývá.
Každopádně poté, co budete mít „připojená“ data, můžete $match
na "usrEmail"
vlastnost ze spojených dat a zahrnout do dotazu.
Pokud jde o skutečný dotaz, protože v podstatě děláte $or
stavu napříč daty z obou kolekcí skutečně nemůžeme $match
dokud se „po“ spojení neprovede.
Pak jsou tu samozřejmě fáze agregace pro $skip
a $limit
také pro vaše stránkování.