@@ -215,27 +215,27 @@ public function cursor($columns = [])
215
215
}
216
216
217
217
/**
218
- * Execute the query as a fresh "select" statement .
218
+ * Return the MongoDB query to be run in the form of an element array like ['method' => [arguments]] .
219
219
*
220
- * @param array $columns
221
- * @param bool $returnLazy
222
- * @return array|static[]|Collection|LazyCollection
220
+ * Example: ['find' => [['name' => 'John Doe'], ['projection' => ['birthday' => 1]]]]
221
+ *
222
+ * @param $columns
223
+ * @return array<string, mixed[]>
223
224
*/
224
- public function getFresh ($ columns = [], $ returnLazy = false )
225
+ public function toMql ($ columns = []): array
225
226
{
226
227
// If no columns have been specified for the select statement, we will set them
227
228
// here to either the passed columns, or the standard default of retrieving
228
229
// all of the columns on the table using the "wildcard" column character.
229
- if ($ this ->columns = == null ) {
230
- $ this -> columns = $ columns ;
230
+ if ($ this ->columns ! == null ) {
231
+ $ columns = $ this -> columns ;
231
232
}
232
233
233
234
// Drop all columns if * is present, MongoDB does not work this way.
234
- if (in_array ('* ' , $ this -> columns )) {
235
- $ this -> columns = [];
235
+ if (in_array ('* ' , $ columns )) {
236
+ $ columns = [];
236
237
}
237
238
238
- // Compile wheres
239
239
$ wheres = $ this ->compileWheres ();
240
240
241
241
// Use MongoDB's aggregation framework when using grouping or aggregation functions.
@@ -254,7 +254,7 @@ public function getFresh($columns = [], $returnLazy = false)
254
254
}
255
255
256
256
// Do the same for other columns that are selected.
257
- foreach ($ this -> columns as $ column ) {
257
+ foreach ($ columns as $ column ) {
258
258
$ key = str_replace ('. ' , '_ ' , $ column );
259
259
260
260
$ group [$ key ] = ['$last ' => '$ ' .$ column ];
@@ -274,26 +274,10 @@ public function getFresh($columns = [], $returnLazy = false)
274
274
$ column = implode ('. ' , $ splitColumns );
275
275
}
276
276
277
- // Null coalense only > 7.2
278
-
279
277
$ aggregations = blank ($ this ->aggregate ['columns ' ]) ? [] : $ this ->aggregate ['columns ' ];
280
278
281
279
if (in_array ('* ' , $ aggregations ) && $ function == 'count ' ) {
282
- // When ORM is paginating, count doesnt need a aggregation, just a cursor operation
283
- // elseif added to use this only in pagination
284
- // https://docs.mongodb.com/manual/reference/method/cursor.count/
285
- // count method returns int
286
-
287
- $ totalResults = $ this ->collection ->count ($ wheres );
288
- // Preserving format expected by framework
289
- $ results = [
290
- [
291
- '_id ' => null ,
292
- 'aggregate ' => $ totalResults ,
293
- ],
294
- ];
295
-
296
- return new Collection ($ results );
280
+ return ['countDocuments ' => [$ wheres , []]];
297
281
} elseif ($ function == 'count ' ) {
298
282
// Translate count into sum.
299
283
$ group ['aggregate ' ] = ['$sum ' => 1 ];
@@ -348,34 +332,23 @@ public function getFresh($columns = [], $returnLazy = false)
348
332
349
333
$ options = $ this ->inheritConnectionOptions ($ options );
350
334
351
- // Execute aggregation
352
- $ results = iterator_to_array ($ this ->collection ->aggregate ($ pipeline , $ options ));
353
-
354
- // Return results
355
- return new Collection ($ results );
335
+ return ['aggregate ' => [$ pipeline , $ options ]];
356
336
} // Distinct query
357
337
elseif ($ this ->distinct ) {
358
338
// Return distinct results directly
359
- $ column = isset ($ this -> columns [0 ]) ? $ this -> columns [0 ] : '_id ' ;
339
+ $ column = isset ($ columns [0 ]) ? $ columns [0 ] : '_id ' ;
360
340
361
341
$ options = $ this ->inheritConnectionOptions ();
362
342
363
- // Execute distinct
364
- $ result = $ this ->collection ->distinct ($ column , $ wheres ?: [], $ options );
365
-
366
- return new Collection ($ result );
343
+ return ['distinct ' => [$ column , $ wheres ?: [], $ options ]];
367
344
} // Normal query
368
345
else {
369
- $ columns = [];
370
-
371
346
// Convert select columns to simple projections.
372
- foreach ($ this ->columns as $ column ) {
373
- $ columns [$ column ] = true ;
374
- }
347
+ $ projection = array_fill_keys ($ columns , true );
375
348
376
349
// Add custom projections.
377
350
if ($ this ->projections ) {
378
- $ columns = array_merge ($ columns , $ this ->projections );
351
+ $ projection = array_merge ($ projection , $ this ->projections );
379
352
}
380
353
$ options = [];
381
354
@@ -395,8 +368,8 @@ public function getFresh($columns = [], $returnLazy = false)
395
368
if ($ this ->hint ) {
396
369
$ options ['hint ' ] = $ this ->hint ;
397
370
}
398
- if ($ columns ) {
399
- $ options ['projection ' ] = $ columns ;
371
+ if ($ projection ) {
372
+ $ options ['projection ' ] = $ projection ;
400
373
}
401
374
402
375
// Fix for legacy support, converts the results to arrays instead of objects.
@@ -409,22 +382,50 @@ public function getFresh($columns = [], $returnLazy = false)
409
382
410
383
$ options = $ this ->inheritConnectionOptions ($ options );
411
384
412
- // Execute query and get MongoCursor
413
- $ cursor = $ this ->collection ->find ($ wheres , $ options );
385
+ return ['find ' => [$ wheres , $ options ]];
386
+ }
387
+ }
414
388
415
- if ($ returnLazy ) {
416
- return LazyCollection::make (function () use ($ cursor ) {
417
- foreach ($ cursor as $ item ) {
418
- yield $ item ;
419
- }
420
- });
421
- }
389
+ /**
390
+ * Execute the query as a fresh "select" statement.
391
+ *
392
+ * @param array $columns
393
+ * @param bool $returnLazy
394
+ * @return array|static[]|Collection|LazyCollection
395
+ */
396
+ public function getFresh ($ columns = [], $ returnLazy = false )
397
+ {
398
+ $ command = $ this ->toMql ($ columns );
399
+ assert (count ($ command ) >= 1 , 'At least one method call is required to execute a query ' );
400
+
401
+ $ result = $ this ->collection ;
402
+ foreach ($ command as $ method => $ arguments ) {
403
+ $ result = call_user_func_array ([$ result , $ method ], $ arguments );
404
+ }
422
405
423
- // Return results as an array with numeric keys
424
- $ results = iterator_to_array ($ cursor , false );
406
+ // countDocuments method returns int, wrap it to the format expected by the framework
407
+ if (is_int ($ result )) {
408
+ $ result = [
409
+ [
410
+ '_id ' => null ,
411
+ 'aggregate ' => $ result ,
412
+ ],
413
+ ];
414
+ }
425
415
426
- return new Collection ($ results );
416
+ if ($ returnLazy ) {
417
+ return LazyCollection::make (function () use ($ result ) {
418
+ foreach ($ result as $ item ) {
419
+ yield $ item ;
420
+ }
421
+ });
422
+ }
423
+
424
+ if ($ result instanceof Cursor) {
425
+ $ result = $ result ->toArray ();
427
426
}
427
+
428
+ return new Collection ($ result );
428
429
}
429
430
430
431
/**
0 commit comments