@@ -29,6 +29,13 @@ class Builder extends BaseBuilder {
2929 */
3030 public $ timeout ;
3131
32+ /**
33+ * Indicate if we are executing a pagination query.
34+ *
35+ * @var bool
36+ */
37+ public $ paginating = false ;
38+
3239 /**
3340 * All of the available clause operators.
3441 *
@@ -140,7 +147,7 @@ public function getFresh($columns = array())
140147 $ wheres = $ this ->compileWheres ();
141148
142149 // 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 )
144151 {
145152 $ group = array ();
146153
@@ -155,12 +162,14 @@ public function getFresh($columns = array())
155162 // this mimics MySQL's behaviour a bit.
156163 $ group [$ column ] = array ('$last ' => '$ ' . $ column );
157164 }
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+ }
164173 }
165174
166175 // Add aggregation functions to the $group part of the aggregation pipeline,
@@ -184,22 +193,26 @@ public function getFresh($columns = array())
184193 }
185194 }
186195
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 )
190199 {
191200 foreach ($ this ->columns as $ column )
192201 {
193- $ key = str_replace ('. ' , '_ ' , $ column );
194-
195- $ group [$ key ] = array ('$last ' => '$ ' . $ column );
202+ $ this ->projections [$ column ] = 1 ;
196203 }
197204 }
198205
206+ // The _id field is mandatory when using grouping.
207+ if ($ group and empty ($ group ['_id ' ]))
208+ {
209+ $ group ['_id ' ] = null ;
210+ }
211+
199212 // Build the aggregation pipeline.
200213 $ pipeline = array ();
201214 if ($ wheres ) $ pipeline [] = array ('$match ' => $ wheres );
202- $ pipeline [] = array ('$group ' => $ group );
215+ if ( $ group ) $ pipeline [] = array ('$group ' => $ group );
203216
204217 // Apply order and limit
205218 if ($ this ->orders ) $ pipeline [] = array ('$sort ' => $ this ->orders );
@@ -370,6 +383,20 @@ public function whereBetween($column, array $values, $boolean = 'and', $not = fa
370383 return $ this ;
371384 }
372385
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+
373400 /**
374401 * Insert a new record into the database.
375402 *
0 commit comments