Можете да направите суров
заявка с aggregate()
който може да използва $lookup
оператор за извършване на „присъединяването“ тук:
$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
ще върне "масив" за целевото поле, съдържащо "няма" или повече съвпадащи записи в предоставения 'localField'
стойност(и), където това е или единствено число, или масив от стойности. Обикновено използваме ObjectId
тук, особено при свързване към 'foreignField'
като _id
.
Това е по-добре от всичко, което може да се направи от страна на клиента, тъй като всяка друга операция би изисквала извършване на множество заявки към базата данни за всеки източник на събиране. $lookup
прави това в една заявка и отговор.
Единствената истинска забележка е, че тъй като това е "отделно" от ORM/ODM, трябва да посочите действителното "име на колекцията", а не това на класа или модела. Така че просто предполагам "потребители"
тук, но може би ще трябва да коригирате това към колекцията си за Потребители
всъщност се нарича.
Така или иначе, след като имате „присъединените“ данни, можете да $match
на "usrEmail"
свойство от обединените данни и включете във вашата заявка.
Що се отнася до действителната заявка, тъй като вие основно правите $or
условие в данните от двете колекции, ние наистина не можем да $matchкод>
докато "след" се извърши присъединяването.
След това, разбира се, има етапите на агрегиране за $skipкод>
и $limit
и за вашата пагинация.