Skip to content

Commit 15e30e7

Browse files
committed
Update aggregation builder Laravel 4.2
1 parent 31774a1 commit 15e30e7

File tree

3 files changed

+134
-16
lines changed

3 files changed

+134
-16
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,5 @@ composer.lock
66
*.sublime-project
77
*.sublime-workspace
88
*.project
9+
10+
.idea

src/Jenssegers/Mongodb/Eloquent/Builder.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,4 +238,10 @@ public function raw($expression = null)
238238
return $results;
239239
}
240240

241+
public function paginate($perPage = null, $columns = array('*')) {
242+
243+
$this->query->addPaginateCols($columns);
244+
return parent::paginate($perPage, $columns);
245+
}
246+
241247
}

src/Jenssegers/Mongodb/Query/Builder.php

Lines changed: 126 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,20 @@ class Builder extends QueryBuilder {
3333
*/
3434
public $timeout;
3535

36+
/**
37+
* Flag for use aggregation
38+
*
39+
* @var bool
40+
*/
41+
protected $useAggregation = false;
42+
43+
/**
44+
* Paginate columns
45+
*
46+
* @var array
47+
*/
48+
protected $paginateCols = [];
49+
3650
/**
3751
* All of the available clause operators.
3852
*
@@ -143,9 +157,11 @@ public function getFresh($columns = array())
143157
$wheres = $this->compileWheres();
144158

145159
// Use MongoDB's aggregation framework when using grouping or aggregation functions.
146-
if ($this->groups or $this->aggregate)
160+
if ($this->groups or $this->aggregate or $this->useAggregation)
147161
{
148162
$group = array();
163+
$project = array();
164+
$projectEndColumns = array();
149165

150166
// Add grouping columns to the $group part of the aggregation pipeline.
151167
if ($this->groups)
@@ -159,17 +175,12 @@ public function getFresh($columns = array())
159175
$group[$column] = array('$last' => '$' . $column);
160176
}
161177
}
162-
else
163-
{
164-
// If we don't use grouping, set the _id to null to prepare the pipeline for
165-
// other aggregation functions.
166-
$group['_id'] = null;
167-
}
168178

169179
// Add aggregation functions to the $group part of the aggregation pipeline,
170180
// these may override previous aggregations.
171181
if ($this->aggregate)
172182
{
183+
173184
$function = $this->aggregate['function'];
174185

175186
foreach ($this->aggregate['columns'] as $column)
@@ -187,25 +198,81 @@ public function getFresh($columns = array())
187198
}
188199
}
189200

190-
// If no aggregation functions are used, we add the additional select columns
191-
// to the pipeline here, aggregating them by $last.
201+
192202
else
193203
{
204+
205+
// If no aggregation functions are used, we add the additional select columns
206+
// to the pipeline here, aggregating them by $last.
194207
foreach ($this->columns as $column)
195208
{
196-
$key = str_replace('.', '_', $column);
209+
if (!in_array($column, $this->paginateCols) ) {
210+
$key = str_replace('.', '_', $column);
197211

198-
$group[$key] = array('$last' => '$' . $column);
212+
$group[$key] = array('$last' => '$' . $column);
213+
}
199214
}
215+
216+
217+
//add cols to filter groups and use mongoDb map/reduce
218+
if ($this->columns) {
219+
220+
if ($this->columns || $this->groups) {
221+
$cols = array_merge((array)$this->columns, (array)$this->groups);
222+
foreach ($cols as $column) {
223+
$key = str_replace('.', '_', $column);
224+
$project[$key] = 1;
225+
}
226+
}
227+
228+
if ($this->columns) {
229+
foreach ($cols as $column) {
230+
$key = str_replace('.', '_', $column);
231+
$projectEndColumns[$key] = 1;
232+
}
233+
}
234+
}
235+
200236
}
201237

238+
202239
// Build the aggregation pipeline.
203240
$pipeline = array();
204241
if ($wheres) $pipeline[] = array('$match' => $wheres);
205-
$pipeline[] = array('$group' => $group);
242+
243+
244+
//filter used columns
245+
if(!empty($project)) {
246+
$pipeline[] = array('$project' => $project);
247+
}
248+
249+
if (!empty($group)) {
250+
if (!isset($group['_id'])) {
251+
// If we don't use grouping, set the _id to null to prepare the pipeline for
252+
// other aggregation functions.
253+
$group['_id'] = null;
254+
}
255+
256+
$pipeline[] = array('$group' => $group);
257+
}
258+
259+
//filter columns
260+
if(!empty($projectEndColumns)) {
261+
$pipeline[] = array('$project' => $projectEndColumns);
262+
}
263+
264+
265+
206266

207267
// Apply order and limit
208-
if ($this->orders) $pipeline[] = array('$sort' => $this->orders);
268+
if ($this->orders) {
269+
if (isset($this->orders['$natural'])) {
270+
unset($this->orders['$natural']);
271+
}
272+
if(!empty($this->orders)) {
273+
$pipeline[] = array('$sort' => $this->orders);
274+
}
275+
}
209276
if ($this->offset) $pipeline[] = array('$skip' => $this->offset);
210277
if ($this->limit) $pipeline[] = array('$limit' => $this->limit);
211278
if ($this->projections) $pipeline[] = array('$project' => $this->projections);
@@ -302,7 +369,6 @@ public function aggregate($function, $columns = array())
302369
if (isset($results[0]))
303370
{
304371
$result = (array) $results[0];
305-
306372
return $result['aggregate'];
307373
}
308374
}
@@ -344,9 +410,54 @@ public function orderBy($column, $direction = 'asc')
344410
$this->orders[$column] = $direction;
345411
}
346412

413+
$this->useAggregation = true;
414+
347415
return $this;
348416
}
349417

418+
/**
419+
* Set the "limit" value of the query.
420+
*
421+
* @param int $value
422+
* @return $this
423+
*/
424+
public function limit($value)
425+
{
426+
$this->useAggregation = true;
427+
428+
return parent::limit((int)$value);
429+
}
430+
431+
/**
432+
* Set the "offset" value of the query.
433+
*
434+
* @param int $value
435+
* @return $this
436+
*/
437+
public function offset($value)
438+
{
439+
$this->useAggregation = true;
440+
441+
return parent::offset((int)$value);
442+
}
443+
444+
445+
public function paginate($perPage = 15, $columns = array('*')) {
446+
447+
$this->addPaginateCols($columns);
448+
return parent::paginate($perPage, $columns);
449+
}
450+
451+
public function addPaginateCols($columns)
452+
{
453+
if (in_array('*', $columns)) {
454+
unset($columns[array_search('*', $columns)]);
455+
}
456+
$this->paginateCols = $this->paginateCols+$columns;
457+
}
458+
459+
460+
350461
/**
351462
* Add a where between statement to the query.
352463
*
@@ -716,12 +827,11 @@ public function convertKey($id)
716827
public function where($column, $operator = null, $value = null, $boolean = 'and')
717828
{
718829
$params = func_get_args();
719-
830+
720831
// Remove the leading $ from operators.
721832
if (func_num_args() == 3)
722833
{
723834
$operator = &$params[1];
724-
725835
if (starts_with($operator, '$'))
726836
{
727837
$operator = substr($operator, 1);

0 commit comments

Comments
 (0)