Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
Y
yii2
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
PSDI Army
yii2
Commits
0e082c17
Commit
0e082c17
authored
Dec 02, 2013
by
Paul Klimov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Aggregation functions added to Mongo Query.
parent
da88e3db
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
138 additions
and
19 deletions
+138
-19
Collection.php
extensions/mongo/Collection.php
+20
-8
Query.php
extensions/mongo/Query.php
+114
-8
ActiveRecordTest.php
tests/unit/extensions/mongo/ActiveRecordTest.php
+4
-3
No files found.
extensions/mongo/Collection.php
View file @
0e082c17
...
...
@@ -202,9 +202,11 @@ class Collection extends Object
}
/**
* @param $pipeline
* @param array $pipelineOperator
* @return array
* Performs aggregation using Mongo Aggregation Framework.
* @param array $pipeline list of pipeline operators, or just the first operator
* @param array $pipelineOperator Additional pipeline operators
* @return array the result of the aggregation.
* @see http://docs.mongodb.org/manual/applications/aggregation/
*/
public
function
aggregate
(
$pipeline
,
$pipelineOperator
=
[])
{
...
...
@@ -213,20 +215,30 @@ class Collection extends Object
}
/**
* Performs aggregation using Mongo Map Reduce mechanism.
* @param mixed $keys
* @param array $initial
* @param \MongoCode|string $reduce
* @param array $options
* @return array
* @param array $initial Initial value of the aggregation counter object.
* @param \MongoCode|string $reduce function that takes two arguments (the current
* document and the aggregation to this point) and does the aggregation.
* Argument will be automatically cast to [[\MongoCode]].
* @param array $options optional parameters to the group command. Valid options include:
* - condition - criteria for including a document in the aggregation.
* - finalize - function called once per unique key that takes the final output of the reduce function.
* @return array the result of the aggregation.
*/
public
function
mapReduce
(
$keys
,
$initial
,
$reduce
,
$options
=
[])
{
if
(
!
(
$reduce
instanceof
\MongoCode
))
{
$reduce
=
new
\MongoCode
(
$reduce
);
$reduce
=
new
\MongoCode
(
(
string
)
$reduce
);
}
if
(
array_key_exists
(
'condition'
,
$options
))
{
$options
[
'condition'
]
=
$this
->
buildCondition
(
$options
[
'condition'
]);
}
if
(
array_key_exists
(
'finalize'
,
$options
))
{
if
(
!
(
$options
[
'finalize'
]
instanceof
\MongoCode
))
{
$options
[
'finalize'
]
=
new
\MongoCode
((
string
)
$options
[
'finalize'
]);
}
}
return
$this
->
mongoCollection
->
group
(
$keys
,
$initial
,
$reduce
,
$options
);
}
...
...
extensions/mongo/Query.php
View file @
0e082c17
...
...
@@ -105,8 +105,8 @@ class Query extends Component implements QueryInterface
/**
* Executes the query and returns all results as an array.
* @param Connection $db the
database
connection used to execute the query.
* If this parameter is not given, the `
db
` application component will be used.
* @param Connection $db the
Mongo
connection used to execute the query.
* If this parameter is not given, the `
mongo
` application component will be used.
* @return array the query results. If the query results in nothing, an empty array will be returned.
*/
public
function
all
(
$db
=
null
)
...
...
@@ -130,8 +130,8 @@ class Query extends Component implements QueryInterface
/**
* Executes the query and returns a single row of result.
* @param Connection $db the
database
connection used to execute the query.
* If this parameter is not given, the `
db
` application component will be used.
* @param Connection $db the
Mongo
connection used to execute the query.
* If this parameter is not given, the `
mongo
` application component will be used.
* @return array|boolean the first row (in terms of an array) of the query result. False is returned if the query
* results in nothing.
*/
...
...
@@ -148,8 +148,8 @@ class Query extends Component implements QueryInterface
/**
* Returns the number of records.
* @param string $q the COUNT expression. Defaults to '*'.
* @param Connection $db the
database
connection used to execute the query.
* If this parameter is not given, the `
db
` application component will be used.
* @param Connection $db the
Mongo
connection used to execute the query.
* If this parameter is not given, the `
mongo
` application component will be used.
* @return integer number of records
*/
public
function
count
(
$q
=
'*'
,
$db
=
null
)
...
...
@@ -160,12 +160,117 @@ class Query extends Component implements QueryInterface
/**
* Returns a value indicating whether the query result contains any row of data.
* @param Connection $db the
database
connection used to execute the query.
* If this parameter is not given, the `
db
` application component will be used.
* @param Connection $db the
Mongo
connection used to execute the query.
* If this parameter is not given, the `
mongo
` application component will be used.
* @return boolean whether the query result contains any row of data.
*/
public
function
exists
(
$db
=
null
)
{
return
$this
->
one
(
$db
)
!==
null
;
}
/**
* Returns the sum of the specified column values.
* @param string $q the column name or expression.
* Make sure you properly quote column names in the expression.
* @param Connection $db the Mongo connection used to execute the query.
* If this parameter is not given, the `mongo` application component will be used.
* @return integer the sum of the specified column values
*/
public
function
sum
(
$q
,
$db
=
null
)
{
return
$this
->
aggregate
(
$q
,
'sum'
,
$db
);
}
/**
* Returns the average of the specified column values.
* @param string $q the column name or expression.
* Make sure you properly quote column names in the expression.
* @param Connection $db the Mongo connection used to execute the query.
* If this parameter is not given, the `mongo` application component will be used.
* @return integer the average of the specified column values.
*/
public
function
average
(
$q
,
$db
=
null
)
{
return
$this
->
aggregate
(
$q
,
'avg'
,
$db
);
}
/**
* Returns the minimum of the specified column values.
* @param string $q the column name or expression.
* Make sure you properly quote column names in the expression.
* @param Connection $db the database connection used to generate the SQL statement.
* If this parameter is not given, the `db` application component will be used.
* @return integer the minimum of the specified column values.
*/
public
function
min
(
$q
,
$db
=
null
)
{
return
$this
->
aggregate
(
$q
,
'min'
,
$db
);
}
/**
* Returns the maximum of the specified column values.
* @param string $q the column name or expression.
* Make sure you properly quote column names in the expression.
* @param Connection $db the Mongo connection used to execute the query.
* If this parameter is not given, the `mongo` application component will be used.
* @return integer the maximum of the specified column values.
*/
public
function
max
(
$q
,
$db
=
null
)
{
return
$this
->
aggregate
(
$q
,
'max'
,
$db
);
}
/**
* Performs the aggregation for the given column.
* @param string $column column name.
* @param string $operator aggregation operator.
* @param Connection $db the database connection used to execute the query.
* @return integer aggregation result.
*/
protected
function
aggregate
(
$column
,
$operator
,
$db
)
{
$collection
=
$this
->
getCollection
(
$db
);
$pipelines
=
[];
if
(
$this
->
where
!==
null
)
{
$pipelines
[]
=
[
'$match'
=>
$collection
->
buildCondition
(
$this
->
where
)];
}
$pipelines
[]
=
[
'$group'
=>
[
'_id'
=>
'1'
,
'total'
=>
[
'$'
.
$operator
=>
'$'
.
$column
],
]
];
$result
=
$collection
->
aggregate
(
$pipelines
);
if
(
!
empty
(
$result
[
'ok'
]))
{
return
$result
[
'result'
][
0
][
'total'
];
}
else
{
return
0
;
}
}
/**
* Returns a list of distinct values for the given column across a collection.
* @param string $q column to use.
* @param Connection $db the Mongo connection used to execute the query.
* If this parameter is not given, the `mongo` application component will be used.
* @return array array of distinct values
*/
public
function
distinct
(
$q
,
$db
=
null
)
{
$collection
=
$this
->
getCollection
(
$db
);
if
(
$this
->
where
!==
null
)
{
$condition
=
$this
->
where
;
}
else
{
$condition
=
[];
}
$result
=
$collection
->
distinct
(
$q
,
$condition
);
if
(
$result
===
false
)
{
return
[];
}
else
{
return
$result
;
}
}
}
\ No newline at end of file
tests/unit/extensions/mongo/ActiveRecordTest.php
View file @
0e082c17
...
...
@@ -83,13 +83,14 @@ class ActiveRecordTest extends MongoTestCase
$this
->
assertTrue
(
$customer
instanceof
Customer
);
$this
->
assertEquals
(
4
,
$customer
->
status
);
// find count, sum, average, min, max,
scalar
// find count, sum, average, min, max,
distinct
$this
->
assertEquals
(
10
,
Customer
::
find
()
->
count
());
$this
->
assertEquals
(
1
,
Customer
::
find
()
->
where
([
'status'
=>
2
])
->
count
());
/*
$this->assertEquals((1+10)/2*10, Customer::find()->sum('status'));
$this
->
assertEquals
((
1
+
10
)
/
2
*
10
,
Customer
::
find
()
->
sum
(
'status'
));
$this
->
assertEquals
((
1
+
10
)
/
2
,
Customer
::
find
()
->
average
(
'status'
));
$this
->
assertEquals
(
1
,
Customer
::
find
()
->
min
(
'status'
));
$this->assertEquals(10, Customer::find()->max('status'));*/
$this
->
assertEquals
(
10
,
Customer
::
find
()
->
max
(
'status'
));
$this
->
assertEquals
(
range
(
1
,
10
),
Customer
::
find
()
->
distinct
(
'status'
));
// scope
$this
->
assertEquals
(
1
,
Customer
::
find
()
->
activeOnly
()
->
count
());
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment