Você pode fazer um
raw
consulta com aggregate()
que pode usar o $lookup
operador para efetuar o "join" aqui: $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 )
));
});
O
$lookup
retornará um "array" para o campo de destino contendo "none" ou mais entradas correspondentes ao 'localField'
fornecido value(s), onde é singular ou uma matriz de valores. Normalmente usamos ObjectId
aqui, especialmente ao vincular ao 'foreignField'
como _id
. Isso é melhor do que qualquer coisa que possa ser feita do lado do cliente, pois qualquer outra operação exigiria fazer várias consultas ao banco de dados para cada fonte de coleta.
$lookup
faz isso em uma única solicitação e resposta. A única observação real é que, como isso é "separado" do ORM/ODM, você precisa especificar o "nome da coleção" real e não o da classe ou modelo. Então, estou apenas presumindo
"usuários"
aqui, mas talvez você precise ajustar isso para o que sua coleção para Usuários
é realmente chamado. De qualquer forma, depois de ter os dados "unidos", você pode
$match
no "usrEmail"
propriedade dos dados combinados e inclua em sua consulta. Quanto à consulta real, já que você está basicamente fazendo um
$or
condição entre os dados de ambas as coleções, não podemos realmente $match
até que "após" a junção seja executada. Então, é claro, existem os estágios de agregação para
$skip
e $limit
para sua paginação também.