@@ -64,109 +64,110 @@ public function getFresh($columns = array('*'))
64
64
// all of the columns on the table using the "wildcard" column character.
65
65
if (is_null ($ this ->columns )) $ this ->columns = $ columns ;
66
66
67
- // Drop all columns if * is present
68
- if (in_array ('* ' , $ this ->columns ))
69
- {
70
- $ this ->columns = array ();
71
- }
67
+ // Drop all columns if * is present, MongoDB does not work this way
68
+ if (in_array ('* ' , $ this ->columns )) $ this ->columns = array ();
72
69
73
70
// Compile wheres
74
71
$ wheres = $ this ->compileWheres ();
75
72
76
- // Use aggregation framework if needed
73
+ // Aggregation query
77
74
if ($ this ->groups || $ this ->aggregate )
78
75
{
79
- $ pipeline = array ();
80
76
$ group = array ();
81
77
82
- // Grouping
78
+ // Apply grouping
83
79
if ($ this ->groups )
84
80
{
85
81
foreach ($ this ->groups as $ column )
86
82
{
83
+ // Mark column as grouped
87
84
$ group ['_id ' ][$ column ] = '$ ' . $ column ;
85
+
86
+ // Aggregate by $last when grouping, this mimics MySQL's behaviour a bit
88
87
$ group [$ column ] = array ('$last ' => '$ ' . $ column );
89
88
}
90
89
}
91
90
else
92
91
{
93
- $ group ['_id ' ] = 0 ;
92
+ // If we don't use grouping, set the _id to null to prepare the pipeline for
93
+ // other aggregation functions
94
+ $ group ['_id ' ] = null ;
94
95
}
95
96
96
- // Columns
97
+ // When additional columns are requested, aggregate them by $last as well
97
98
foreach ($ this ->columns as $ column )
98
99
{
99
- $ group [$ column ] = array ('$last ' => '$ ' . $ column );
100
+ // Replace possible dots in subdocument queries with underscores
101
+ $ key = str_replace ('. ' , '_ ' , $ column );
102
+ $ group [$ key ] = array ('$last ' => '$ ' . $ column );
100
103
}
101
104
102
- // Apply aggregation functions
105
+ // Apply aggregation functions, these may override previous aggregations
103
106
if ($ this ->aggregate )
104
107
{
105
108
$ function = $ this ->aggregate ['function ' ];
106
109
107
110
foreach ($ this ->aggregate ['columns ' ] as $ column )
108
111
{
112
+ // Replace possible dots in subdocument queries with underscores
113
+ $ key = str_replace ('. ' , '_ ' , $ column );
114
+
109
115
// Translate count into sum
110
116
if ($ function == 'count ' )
111
117
{
112
- $ group [$ column ] = array ('$sum ' => 1 );
118
+ $ group [$ key ] = array ('$sum ' => 1 );
113
119
}
114
120
// Pass other functions directly
115
121
else
116
122
{
117
- // Normally this aggregate function would overwrite the
118
- // $last group set above, but since we are modifying
119
- // the string, we need to unset it directly.
120
- if (isset ($ group [$ column ]))
121
- {
122
- unset($ group [$ column ]);
123
- }
124
-
125
- $ key = str_replace ('. ' , '_ ' , $ column );
126
123
$ group [$ key ] = array ('$ ' . $ function => '$ ' . $ column );
127
124
}
128
125
}
129
126
}
130
127
131
- if ($ wheres ) $ pipeline [] = array ('$match ' => $ wheres );
132
-
128
+ // Build pipeline
129
+ $ pipeline = array ();
130
+ if ($ wheres ) $ pipeline [] = array ('$match ' => $ wheres );
133
131
$ pipeline [] = array ('$group ' => $ group );
134
132
135
133
// Apply order and limit
136
134
if ($ this ->orders ) $ pipeline [] = array ('$sort ' => $ this ->orders );
137
135
if ($ this ->offset ) $ pipeline [] = array ('$skip ' => $ this ->offset );
138
136
if ($ this ->limit ) $ pipeline [] = array ('$limit ' => $ this ->limit );
139
137
138
+ // Execute aggregation
140
139
$ results = $ this ->collection ->aggregate ($ pipeline );
141
140
142
141
// Return results
143
142
return $ results ['result ' ];
144
143
}
144
+
145
+ // Distinct query
146
+ else if ($ this ->distinct )
147
+ {
148
+ // Return distinct results directly
149
+ $ column = isset ($ this ->columns [0 ]) ? $ this ->columns [0 ] : '_id ' ;
150
+ return $ this ->collection ->distinct ($ column , $ wheres );
151
+ }
152
+
153
+ // Normal query
145
154
else
146
155
{
147
- // Execute distinct
148
- if ($ this ->distinct )
149
- {
150
- $ column = isset ($ this ->columns [0 ]) ? $ this ->columns [0 ] : '_id ' ;
151
- return $ this ->collection ->distinct ($ column , $ wheres );
152
- }
153
-
154
- // Columns
155
156
$ columns = array ();
156
157
foreach ($ this ->columns as $ column )
157
158
{
158
159
$ columns [$ column ] = true ;
159
160
}
160
161
161
- // Get the MongoCursor
162
+ // Execute query and get MongoCursor
162
163
$ cursor = $ this ->collection ->find ($ wheres , $ columns );
163
164
164
165
// Apply order, offset and limit
165
166
if ($ this ->orders ) $ cursor ->sort ($ this ->orders );
166
167
if ($ this ->offset ) $ cursor ->skip ($ this ->offset );
167
168
if ($ this ->limit ) $ cursor ->limit ($ this ->limit );
168
169
169
- // Return results
170
+ // Return results as an array with numeric keys
170
171
return iterator_to_array ($ cursor , false );
171
172
}
172
173
}
@@ -212,6 +213,7 @@ public function aggregate($function, $columns = array('*'))
212
213
213
214
if (isset ($ results [0 ]))
214
215
{
216
+ // Replace possible dots in subdocument queries with underscores
215
217
$ key = str_replace ('. ' , '_ ' , $ columns [0 ]);
216
218
return $ results [0 ][$ key ];
217
219
}
@@ -280,7 +282,7 @@ public function insert(array $values)
280
282
{
281
283
// As soon as we find a value that is not an array we assume the user is
282
284
// inserting a single document.
283
- if (!is_array ($ value ))
285
+ if (!is_array ($ value ))
284
286
{
285
287
$ batch = false ; break ;
286
288
}
@@ -532,7 +534,7 @@ protected function performUpdate($query)
532
534
533
535
/**
534
536
* Convert a key to MongoID if needed
535
- *
537
+ *
536
538
* @param mixed $id
537
539
* @return mixed
538
540
*/
@@ -558,7 +560,7 @@ protected function compileWheres()
558
560
// The new list of compiled wheres
559
561
$ wheres = array ();
560
562
561
- foreach ($ this ->wheres as $ i => &$ where )
563
+ foreach ($ this ->wheres as $ i => &$ where )
562
564
{
563
565
// Convert id's
564
566
if (isset ($ where ['column ' ]) && $ where ['column ' ] == '_id ' )
0 commit comments