Skip to content

Update aggregation builder Laravel 4.2 #428

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ composer.lock
*.sublime-project
*.sublime-workspace
*.project

.idea
6 changes: 6 additions & 0 deletions src/Jenssegers/Mongodb/Eloquent/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -238,4 +238,10 @@ public function raw($expression = null)
return $results;
}

public function paginate($perPage = null, $columns = array('*')) {

$this->query->addPaginateCols($columns);
return parent::paginate($perPage, $columns);
}

}
142 changes: 126 additions & 16 deletions src/Jenssegers/Mongodb/Query/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,20 @@ class Builder extends QueryBuilder {
*/
public $timeout;

/**
* Flag for use aggregation
*
* @var bool
*/
protected $useAggregation = false;

/**
* Paginate columns
*
* @var array
*/
protected $paginateCols = [];

/**
* All of the available clause operators.
*
Expand Down Expand Up @@ -143,9 +157,11 @@ public function getFresh($columns = array())
$wheres = $this->compileWheres();

// Use MongoDB's aggregation framework when using grouping or aggregation functions.
if ($this->groups or $this->aggregate)
if ($this->groups or $this->aggregate or $this->useAggregation)
{
$group = array();
$project = array();
$projectEndColumns = array();

// Add grouping columns to the $group part of the aggregation pipeline.
if ($this->groups)
Expand All @@ -159,17 +175,12 @@ public function getFresh($columns = array())
$group[$column] = array('$last' => '$' . $column);
}
}
else
{
// If we don't use grouping, set the _id to null to prepare the pipeline for
// other aggregation functions.
$group['_id'] = null;
}

// Add aggregation functions to the $group part of the aggregation pipeline,
// these may override previous aggregations.
if ($this->aggregate)
{

$function = $this->aggregate['function'];

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

// If no aggregation functions are used, we add the additional select columns
// to the pipeline here, aggregating them by $last.

else
{

// If no aggregation functions are used, we add the additional select columns
// to the pipeline here, aggregating them by $last.
foreach ($this->columns as $column)
{
$key = str_replace('.', '_', $column);
if (!in_array($column, $this->paginateCols) ) {
$key = str_replace('.', '_', $column);

$group[$key] = array('$last' => '$' . $column);
$group[$key] = array('$last' => '$' . $column);
}
}


//add cols to filter groups and use mongoDb map/reduce
if ($this->columns) {

if ($this->columns || $this->groups) {
$cols = array_merge((array)$this->columns, (array)$this->groups);
foreach ($cols as $column) {
$key = str_replace('.', '_', $column);
$project[$key] = 1;
}
}

if ($this->columns) {
foreach ($cols as $column) {
$key = str_replace('.', '_', $column);
$projectEndColumns[$key] = 1;
}
}
}

}


// Build the aggregation pipeline.
$pipeline = array();
if ($wheres) $pipeline[] = array('$match' => $wheres);
$pipeline[] = array('$group' => $group);


//filter used columns
if(!empty($project)) {
$pipeline[] = array('$project' => $project);
}

if (!empty($group)) {
if (!isset($group['_id'])) {
// If we don't use grouping, set the _id to null to prepare the pipeline for
// other aggregation functions.
$group['_id'] = null;
}

$pipeline[] = array('$group' => $group);
}

//filter columns
if(!empty($projectEndColumns)) {
$pipeline[] = array('$project' => $projectEndColumns);
}




// Apply order and limit
if ($this->orders) $pipeline[] = array('$sort' => $this->orders);
if ($this->orders) {
if (isset($this->orders['$natural'])) {
unset($this->orders['$natural']);
}
if(!empty($this->orders)) {
$pipeline[] = array('$sort' => $this->orders);
}
}
if ($this->offset) $pipeline[] = array('$skip' => $this->offset);
if ($this->limit) $pipeline[] = array('$limit' => $this->limit);
if ($this->projections) $pipeline[] = array('$project' => $this->projections);
Expand Down Expand Up @@ -302,7 +369,6 @@ public function aggregate($function, $columns = array())
if (isset($results[0]))
{
$result = (array) $results[0];

return $result['aggregate'];
}
}
Expand Down Expand Up @@ -344,9 +410,54 @@ public function orderBy($column, $direction = 'asc')
$this->orders[$column] = $direction;
}

$this->useAggregation = true;

return $this;
}

/**
* Set the "limit" value of the query.
*
* @param int $value
* @return $this
*/
public function limit($value)
{
$this->useAggregation = true;

return parent::limit((int)$value);
}

/**
* Set the "offset" value of the query.
*
* @param int $value
* @return $this
*/
public function offset($value)
{
$this->useAggregation = true;

return parent::offset((int)$value);
}


public function paginate($perPage = 15, $columns = array('*')) {

$this->addPaginateCols($columns);
return parent::paginate($perPage, $columns);
}

public function addPaginateCols($columns)
{
if (in_array('*', $columns)) {
unset($columns[array_search('*', $columns)]);
}
$this->paginateCols = $this->paginateCols+$columns;
}



/**
* Add a where between statement to the query.
*
Expand Down Expand Up @@ -716,12 +827,11 @@ public function convertKey($id)
public function where($column, $operator = null, $value = null, $boolean = 'and')
{
$params = func_get_args();

// Remove the leading $ from operators.
if (func_num_args() == 3)
{
$operator = &$params[1];

if (starts_with($operator, '$'))
{
$operator = substr($operator, 1);
Expand Down