Anda dapat melakukan raw
kueri dengan aggregate()
yang dapat menggunakan $lookup
operator untuk melakukan "bergabung" di sini:
$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
akan mengembalikan "array" untuk bidang target yang berisi "none" atau lebih entri yang cocok dengan 'localField'
yang disediakan value(s), di mana itu adalah tunggal atau array nilai. Biasanya kami menggunakan ObjectId
di sini, terutama saat menautkan ke 'foreignField'
sebagai _id
.
Ini lebih baik daripada apa pun yang dapat dilakukan di sisi klien, karena operasi lain mana pun akan memerlukan pembuatan beberapa kueri ke database untuk setiap sumber koleksi. $lookup
melakukan ini dalam satu permintaan dan tanggapan.
Satu-satunya catatan nyata adalah karena ini "terpisah" dari ORM/ODM, Anda perlu menentukan "nama koleksi" yang sebenarnya dan bukan kelas atau model. Jadi saya hanya menganggap "users"
di sini, tetapi Anda mungkin perlu menyesuaikannya dengan koleksi Anda untuk Users
sebenarnya disebut.
Bagaimanapun, setelah Anda memiliki data "bergabung" maka Anda dapat $match
pada "usrEmail"
properti dari data yang digabungkan, dan sertakan dalam kueri Anda.
Adapun kueri yang sebenarnya, karena pada dasarnya Anda melakukan $or
kondisi di seluruh data dari kedua koleksi, kami tidak dapat benar-benar $match
sampai "setelah" penggabungan dilakukan.
Lalu tentu saja ada tahapan agregasi untuk $skip
dan $limit
untuk pagination Anda juga.