@@ -29,6 +29,13 @@ class Builder extends BaseBuilder {
29
29
*/
30
30
public $ timeout ;
31
31
32
+ /**
33
+ * Indicate if we are executing a pagination query.
34
+ *
35
+ * @var bool
36
+ */
37
+ public $ paginating = false ;
38
+
32
39
/**
33
40
* All of the available clause operators.
34
41
*
@@ -140,7 +147,7 @@ public function getFresh($columns = array())
140
147
$ wheres = $ this ->compileWheres ();
141
148
142
149
// Use MongoDB's aggregation framework when using grouping or aggregation functions.
143
- if ($ this ->groups or $ this ->aggregate )
150
+ if ($ this ->groups or $ this ->aggregate or $ this -> paginating )
144
151
{
145
152
$ group = array ();
146
153
@@ -155,12 +162,14 @@ public function getFresh($columns = array())
155
162
// this mimics MySQL's behaviour a bit.
156
163
$ group [$ column ] = array ('$last ' => '$ ' . $ column );
157
164
}
158
- }
159
- else
160
- {
161
- // If we don't use grouping, set the _id to null to prepare the pipeline for
162
- // other aggregation functions.
163
- $ group ['_id ' ] = null ;
165
+
166
+ // Do the same for other columns that are selected.
167
+ foreach ($ this ->columns as $ column )
168
+ {
169
+ $ key = str_replace ('. ' , '_ ' , $ column );
170
+
171
+ $ group [$ key ] = array ('$last ' => '$ ' . $ column );
172
+ }
164
173
}
165
174
166
175
// Add aggregation functions to the $group part of the aggregation pipeline,
@@ -184,22 +193,26 @@ public function getFresh($columns = array())
184
193
}
185
194
}
186
195
187
- // If no aggregation functions are used , we add the additional select columns
188
- // to the pipeline here, aggregating them by $last .
189
- else
196
+ // When using pagination , we limit the number of returned columns
197
+ // by adding a projection .
198
+ if ( $ this -> paginating )
190
199
{
191
200
foreach ($ this ->columns as $ column )
192
201
{
193
- $ key = str_replace ('. ' , '_ ' , $ column );
194
-
195
- $ group [$ key ] = array ('$last ' => '$ ' . $ column );
202
+ $ this ->projections [$ column ] = 1 ;
196
203
}
197
204
}
198
205
206
+ // The _id field is mandatory when using grouping.
207
+ if ($ group and empty ($ group ['_id ' ]))
208
+ {
209
+ $ group ['_id ' ] = null ;
210
+ }
211
+
199
212
// Build the aggregation pipeline.
200
213
$ pipeline = array ();
201
214
if ($ wheres ) $ pipeline [] = array ('$match ' => $ wheres );
202
- $ pipeline [] = array ('$group ' => $ group );
215
+ if ( $ group ) $ pipeline [] = array ('$group ' => $ group );
203
216
204
217
// Apply order and limit
205
218
if ($ this ->orders ) $ pipeline [] = array ('$sort ' => $ this ->orders );
@@ -370,6 +383,20 @@ public function whereBetween($column, array $values, $boolean = 'and', $not = fa
370
383
return $ this ;
371
384
}
372
385
386
+ /**
387
+ * Set the limit and offset for a given page.
388
+ *
389
+ * @param int $page
390
+ * @param int $perPage
391
+ * @return \Illuminate\Database\Query\Builder|static
392
+ */
393
+ public function forPage ($ page , $ perPage = 15 )
394
+ {
395
+ $ this ->paginating = true ;
396
+
397
+ return $ this ->skip (($ page - 1 ) * $ perPage )->take ($ perPage );
398
+ }
399
+
373
400
/**
374
401
* Insert a new record into the database.
375
402
*
0 commit comments