@@ -63,7 +63,7 @@ public function __construct(Connection $connection)
63
63
* @param array $columns
64
64
* @return mixed
65
65
*/
66
- public function find ($ id , $ columns = array (' * ' ))
66
+ public function find ($ id , $ columns = array ())
67
67
{
68
68
return $ this ->where ('_id ' , '= ' , $ this ->convertKey ($ id ))->first ($ columns );
69
69
}
@@ -74,7 +74,7 @@ public function find($id, $columns = array('*'))
74
74
* @param array $columns
75
75
* @return array|static[]
76
76
*/
77
- public function getFresh ($ columns = array (' * ' ))
77
+ public function getFresh ($ columns = array ())
78
78
{
79
79
$ start = microtime (true );
80
80
@@ -83,68 +83,69 @@ public function getFresh($columns = array('*'))
83
83
// all of the columns on the table using the "wildcard" column character.
84
84
if (is_null ($ this ->columns )) $ this ->columns = $ columns ;
85
85
86
- // Drop all columns if * is present, MongoDB does not work this way
86
+ // Drop all columns if * is present, MongoDB does not work this way.
87
87
if (in_array ('* ' , $ this ->columns )) $ this ->columns = array ();
88
88
89
89
// Compile wheres
90
90
$ wheres = $ this ->compileWheres ();
91
91
92
- // Aggregation query
92
+ // Use MongoDB's aggregation framework when using grouping or aggregation functions.
93
93
if ($ this ->groups || $ this ->aggregate )
94
94
{
95
95
$ group = array ();
96
96
97
- // Apply grouping
97
+ // Add grouping columns to the $group part of the aggregation pipeline.
98
98
if ($ this ->groups )
99
99
{
100
100
foreach ($ this ->groups as $ column )
101
101
{
102
- // Mark column as grouped
103
102
$ group ['_id ' ][$ column ] = '$ ' . $ column ;
104
103
105
- // Aggregate by $last when grouping, this mimics MySQL's behaviour a bit
104
+ // When grouping, also add the $last operator to each grouped field,
105
+ // this mimics MySQL's behaviour a bit.
106
106
$ group [$ column ] = array ('$last ' => '$ ' . $ column );
107
107
}
108
108
}
109
109
else
110
110
{
111
111
// If we don't use grouping, set the _id to null to prepare the pipeline for
112
- // other aggregation functions
112
+ // other aggregation functions.
113
113
$ group ['_id ' ] = null ;
114
114
}
115
115
116
- // When additional columns are requested, aggregate them by $last as well
117
- foreach ($ this ->columns as $ column )
118
- {
119
- // Replace possible dots in subdocument queries with underscores
120
- $ key = str_replace ('. ' , '_ ' , $ column );
121
- $ group [$ key ] = array ('$last ' => '$ ' . $ column );
122
- }
123
-
124
- // Apply aggregation functions, these may override previous aggregations
116
+ // Add aggregation functions to the $group part of the aggregation pipeline,
117
+ // these may override previous aggregations.
125
118
if ($ this ->aggregate )
126
119
{
127
120
$ function = $ this ->aggregate ['function ' ];
128
121
129
122
foreach ($ this ->aggregate ['columns ' ] as $ column )
130
123
{
131
- // Replace possible dots in subdocument queries with underscores
132
- $ key = str_replace ('. ' , '_ ' , $ column );
133
-
134
- // Translate count into sum
124
+ // Translate count into sum.
135
125
if ($ function == 'count ' )
136
126
{
137
- $ group [$ key ] = array ('$sum ' => 1 );
127
+ $ group [' aggregate ' ] = array ('$sum ' => 1 );
138
128
}
139
- // Pass other functions directly
129
+ // Pass other functions directly.
140
130
else
141
131
{
142
- $ group [$ key ] = array ('$ ' . $ function => '$ ' . $ column );
132
+ $ group [' aggregate ' ] = array ('$ ' . $ function => '$ ' . $ column );
143
133
}
144
134
}
145
135
}
146
136
147
- // Build pipeline
137
+ // If no aggregation functions are used, we add the additional select columns
138
+ // to the pipeline here, aggregating them by $last.
139
+ else
140
+ {
141
+ foreach ($ this ->columns as $ column )
142
+ {
143
+ $ key = str_replace ('. ' , '_ ' , $ column );
144
+ $ group [$ key ] = array ('$last ' => '$ ' . $ column );
145
+ }
146
+ }
147
+
148
+ // Build the aggregation pipeline.
148
149
$ pipeline = array ();
149
150
if ($ wheres ) $ pipeline [] = array ('$match ' => $ wheres );
150
151
$ pipeline [] = array ('$group ' => $ group );
@@ -238,7 +239,7 @@ public function generateCacheKey()
238
239
* @param array $columns
239
240
* @return mixed
240
241
*/
241
- public function aggregate ($ function , $ columns = array (' * ' ))
242
+ public function aggregate ($ function , $ columns = array ())
242
243
{
243
244
$ this ->aggregate = compact ('function ' , 'columns ' );
244
245
@@ -251,9 +252,9 @@ public function aggregate($function, $columns = array('*'))
251
252
252
253
if (isset ($ results [0 ]))
253
254
{
254
- // Replace possible dots in subdocument queries with underscores
255
- $ key = str_replace ( ' . ' , ' _ ' , $ columns [ 0 ]);
256
- return $ results [ 0 ][ $ key ];
255
+ $ result = ( array ) $ results [ 0 ];
256
+
257
+ return $ result [ ' aggregate ' ];
257
258
}
258
259
}
259
260
0 commit comments