MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Comment faire correspondre les collections jointes à l'aide de Laravel et MongoDB ?

Vous pouvez faire un raw requête avec aggregate() qui peut utiliser le $lookup opérateur pour effectuer la "jointure" ici :

  $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 )
     ));
  });

Le $lookup renverra un "tableau" pour le champ cible contenant "aucun" ou plusieurs entrées correspondantes au 'localField' fourni valeur(s), où il s'agit soit d'un singulier, soit d'un tableau de valeurs. Généralement, nous utilisons ObjectId ici, en particulier lors de la liaison au 'foreignField' comme _id .

C'est mieux que tout ce qui peut être fait côté client, car toute autre opération nécessiterait d'effectuer plusieurs requêtes dans la base de données pour chaque source de collecte. $lookup le fait en une seule requête et réponse.

La seule vraie note est que parce que c'est "séparé" de l'ORM/ODM, vous devez spécifier le "nom de collection" réel et non celui de la classe ou du modèle. Donc je présume juste "users" ici, mais vous devrez peut-être ajuster cela à ce que votre collection pour Users est réellement appelé.

Quoi qu'il en soit, une fois que vous avez les données "jointes", vous pouvez $match sur le "usrEmail" propriété à partir des données jointes et incluez-les dans votre requête.

En ce qui concerne la requête proprement dite, puisque vous faites essentiellement un $or condition sur les données des deux collections, nous ne pouvons pas vraiment $match jusqu'à "après" la jointure.

Ensuite, bien sûr, il y a les étapes d'agrégation pour $skip et $limit pour votre pagination également.