3
3
namespace MongoDB \Laravel \Tests \Eloquent ;
4
4
5
5
use Illuminate \Database \Eloquent \Builder ;
6
+ use Illuminate \Support \Collection ;
6
7
use Illuminate \Support \Facades \DB ;
7
8
use MongoDB \Laravel \Eloquent \Model ;
8
9
use MongoDB \Laravel \Tests \TestCase ;
9
10
10
11
use function count ;
12
+ use function ksort ;
11
13
12
14
class EloquentWithAggregateTest extends TestCase
13
15
{
14
16
protected function tearDown (): void
15
17
{
16
- EloquentWithCountModel1 ::truncate ();
17
- EloquentWithCountModel2 ::truncate ();
18
- EloquentWithCountModel3 ::truncate ();
19
- EloquentWithCountModel4 ::truncate ();
18
+ EloquentWithAggregateModel1 ::truncate ();
19
+ EloquentWithAggregateModel2 ::truncate ();
20
+ EloquentWithAggregateModel3 ::truncate ();
21
+ EloquentWithAggregateModel4 ::truncate ();
20
22
21
23
parent ::tearDown ();
22
24
}
23
25
24
26
public function testWithAggregate ()
25
27
{
26
- EloquentWithCountModel1 ::create (['id ' => 1 ]);
27
- $ one = EloquentWithCountModel1 ::create (['id ' => 2 ]);
28
+ EloquentWithAggregateModel1 ::create (['id ' => 1 ]);
29
+ $ one = EloquentWithAggregateModel1 ::create (['id ' => 2 ]);
28
30
$ one ->twos ()->create (['value ' => 4 ]);
29
31
$ one ->twos ()->create (['value ' => 6 ]);
30
32
31
- $ results = EloquentWithCountModel1 ::withCount ('twos ' )->where ('id ' , 2 );
32
- $ this -> assertSame ([
33
+ $ results = EloquentWithAggregateModel1 ::withCount ('twos ' )->where ('id ' , 2 );
34
+ self :: assertSameResults ([
33
35
['id ' => 2 , 'twos_count ' => 2 ],
34
- ], $ results ->get ()-> toArray () );
36
+ ], $ results ->get ());
35
37
36
- $ results = EloquentWithCountModel1 ::withMax ('twos ' , 'value ' )->where ('id ' , 2 );
37
- $ this -> assertSame ([
38
+ $ results = EloquentWithAggregateModel1 ::withMax ('twos ' , 'value ' )->where ('id ' , 2 );
39
+ self :: assertSameResults ([
38
40
['id ' => 2 , 'twos_max ' => 6 ],
39
- ], $ results ->get ()-> toArray () );
41
+ ], $ results ->get ());
40
42
41
- $ results = EloquentWithCountModel1 ::withMin ('twos ' , 'value ' )->where ('id ' , 2 );
42
- $ this -> assertSame ([
43
+ $ results = EloquentWithAggregateModel1 ::withMin ('twos ' , 'value ' )->where ('id ' , 2 );
44
+ self :: assertSameResults ([
43
45
['id ' => 2 , 'twos_min ' => 4 ],
44
- ], $ results ->get ()-> toArray () );
46
+ ], $ results ->get ());
45
47
46
- $ results = EloquentWithCountModel1 ::withAvg ('twos ' , 'value ' )->where ('id ' , 2 );
47
- $ this -> assertSame ([
48
+ $ results = EloquentWithAggregateModel1 ::withAvg ('twos ' , 'value ' )->where ('id ' , 2 );
49
+ self :: assertSameResults ([
48
50
['id ' => 2 , 'twos_avg ' => 5.0 ],
49
- ], $ results ->get ()->toArray ());
51
+ ], $ results ->get ());
52
+ }
53
+
54
+ public function testWithAggregateEmbed ()
55
+ {
56
+ EloquentWithAggregateModel1::create (['id ' => 1 ]);
57
+ $ one = EloquentWithAggregateModel1::create (['id ' => 2 ]);
58
+ $ one ->embeddeds ()->create (['value ' => 4 ]);
59
+ $ one ->embeddeds ()->create (['value ' => 6 ]);
60
+
61
+ $ results = EloquentWithAggregateModel1::withCount ('embeddeds ' )->select ('id ' )->where ('id ' , 2 );
62
+ self ::assertSameResults ([
63
+ ['id ' => 2 , 'embeddeds_count ' => 2 ],
64
+ ], $ results ->get ());
65
+
66
+ $ results = EloquentWithAggregateModel1::withMax ('embeddeds ' , 'value ' )->select ('id ' )->where ('id ' , 2 );
67
+ self ::assertSameResults ([
68
+ ['id ' => 2 , 'embeddeds_max ' => 6 ],
69
+ ], $ results ->get ());
70
+
71
+ $ results = EloquentWithAggregateModel1::withMin ('embeddeds ' , 'value ' )->select ('id ' )->where ('id ' , 2 );
72
+ self ::assertSameResults ([
73
+ ['id ' => 2 , 'embeddeds_min ' => 4 ],
74
+ ], $ results ->get ());
75
+
76
+ $ results = EloquentWithAggregateModel1::withAvg ('embeddeds ' , 'value ' )->select ('id ' )->where ('id ' , 2 );
77
+ self ::assertSameResults ([
78
+ ['id ' => 2 , 'embeddeds_avg ' => 5.0 ],
79
+ ], $ results ->get ());
50
80
}
51
81
52
82
public function testWithAggregateFiltered ()
53
83
{
54
- EloquentWithCountModel1 ::create (['id ' => 1 ]);
55
- $ one = EloquentWithCountModel1 ::create (['id ' => 2 ]);
84
+ EloquentWithAggregateModel1 ::create (['id ' => 1 ]);
85
+ $ one = EloquentWithAggregateModel1 ::create (['id ' => 2 ]);
56
86
$ one ->twos ()->create (['value ' => 4 ]);
57
87
$ one ->twos ()->create (['value ' => 6 ]);
58
88
$ one ->twos ()->create (['value ' => 8 ]);
59
89
$ filter = static function (Builder $ query ) {
60
90
$ query ->where ('value ' , '<= ' , 6 );
61
91
};
62
92
63
- $ results = EloquentWithCountModel1 ::withCount (['twos ' => $ filter ])->where ('id ' , 2 );
64
- $ this -> assertSame ([
93
+ $ results = EloquentWithAggregateModel1 ::withCount (['twos ' => $ filter ])->where ('id ' , 2 );
94
+ self :: assertSameResults ([
65
95
['id ' => 2 , 'twos_count ' => 2 ],
66
- ], $ results ->get ()-> toArray () );
96
+ ], $ results ->get ());
67
97
68
- $ results = EloquentWithCountModel1 ::withMax (['twos ' => $ filter ], 'value ' )->where ('id ' , 2 );
69
- $ this -> assertSame ([
98
+ $ results = EloquentWithAggregateModel1 ::withMax (['twos ' => $ filter ], 'value ' )->where ('id ' , 2 );
99
+ self :: assertSameResults ([
70
100
['id ' => 2 , 'twos_max ' => 6 ],
71
- ], $ results ->get ()-> toArray () );
101
+ ], $ results ->get ());
72
102
73
- $ results = EloquentWithCountModel1 ::withMin (['twos ' => $ filter ], 'value ' )->where ('id ' , 2 );
74
- $ this -> assertSame ([
103
+ $ results = EloquentWithAggregateModel1 ::withMin (['twos ' => $ filter ], 'value ' )->where ('id ' , 2 );
104
+ self :: assertSameResults ([
75
105
['id ' => 2 , 'twos_min ' => 4 ],
76
- ], $ results ->get ()-> toArray () );
106
+ ], $ results ->get ());
77
107
78
- $ results = EloquentWithCountModel1 ::withAvg (['twos ' => $ filter ], 'value ' )->where ('id ' , 2 );
79
- $ this -> assertSame ([
108
+ $ results = EloquentWithAggregateModel1 ::withAvg (['twos ' => $ filter ], 'value ' )->where ('id ' , 2 );
109
+ self :: assertSameResults ([
80
110
['id ' => 2 , 'twos_avg ' => 5.0 ],
81
- ], $ results ->get ()->toArray ());
111
+ ], $ results ->get ());
112
+ }
113
+
114
+ public function testWithAggregateEmbedFiltered ()
115
+ {
116
+ self ::markTestSkipped ('EmbedsMany does not support filtering. $filter requires an expression but the Query Builder generates query predicates. ' );
117
+
118
+ EloquentWithAggregateModel1::create (['id ' => 1 ]);
119
+ $ one = EloquentWithAggregateModel1::create (['id ' => 2 ]);
120
+ $ one ->embeddeds ()->create (['value ' => 4 ]);
121
+ $ one ->embeddeds ()->create (['value ' => 6 ]);
122
+ $ one ->embeddeds ()->create (['value ' => 8 ]);
123
+ $ filter = static function (Builder $ query ) {
124
+ $ query ->where ('value ' , '<= ' , 6 );
125
+ };
126
+
127
+ $ results = EloquentWithAggregateModel1::withCount (['embeddeds ' => $ filter ])->where ('id ' , 2 );
128
+ self ::assertSameResults ([
129
+ ['id ' => 2 , 'embeddeds_count ' => 2 ],
130
+ ], $ results ->get ());
131
+
132
+ $ results = EloquentWithAggregateModel1::withMax (['embeddeds ' => $ filter ], 'value ' )->where ('id ' , 2 );
133
+ self ::assertSameResults ([
134
+ ['id ' => 2 , 'embeddeds_max ' => 6 ],
135
+ ], $ results ->get ());
136
+
137
+ $ results = EloquentWithAggregateModel1::withMin (['embeddeds ' => $ filter ], 'value ' )->where ('id ' , 2 );
138
+ self ::assertSameResults ([
139
+ ['id ' => 2 , 'embeddeds_min ' => 4 ],
140
+ ], $ results ->get ());
141
+
142
+ $ results = EloquentWithAggregateModel1::withAvg (['embeddeds ' => $ filter ], 'value ' )->where ('id ' , 2 );
143
+ self ::assertSameResults ([
144
+ ['id ' => 2 , 'embeddeds_avg ' => 5.0 ],
145
+ ], $ results ->get ());
82
146
}
83
147
84
148
public function testWithAggregateMultipleResults ()
85
149
{
86
150
$ connection = DB ::connection ('mongodb ' );
87
151
$ ones = [
88
- EloquentWithCountModel1 ::create (['id ' => 1 ]),
89
- EloquentWithCountModel1 ::create (['id ' => 2 ]),
90
- EloquentWithCountModel1 ::create (['id ' => 3 ]),
91
- EloquentWithCountModel1 ::create (['id ' => 4 ]),
152
+ EloquentWithAggregateModel1 ::create (['id ' => 1 ]),
153
+ EloquentWithAggregateModel1 ::create (['id ' => 2 ]),
154
+ EloquentWithAggregateModel1 ::create (['id ' => 3 ]),
155
+ EloquentWithAggregateModel1 ::create (['id ' => 4 ]),
92
156
];
93
157
94
158
$ ones [0 ]->twos ()->create (['value ' => 1 ]);
@@ -101,88 +165,103 @@ public function testWithAggregateMultipleResults()
101
165
$ connection ->enableQueryLog ();
102
166
103
167
// Count
104
- $ results = EloquentWithCountModel1 ::withCount ([
168
+ $ results = EloquentWithAggregateModel1 ::withCount ([
105
169
'twos ' => function ($ query ) {
106
170
$ query ->where ('value ' , '>= ' , 2 );
107
171
},
108
172
]);
109
173
110
- $ this -> assertSame ([
174
+ self :: assertSameResults ([
111
175
['id ' => 1 , 'twos_count ' => 2 ],
112
176
['id ' => 2 , 'twos_count ' => 0 ],
113
177
['id ' => 3 , 'twos_count ' => 1 ],
114
178
['id ' => 4 , 'twos_count ' => 0 ],
115
- ], $ results ->get ()-> toArray () );
179
+ ], $ results ->get ());
116
180
117
- $ this -> assertSame (2 , count ($ connection ->getQueryLog ()));
181
+ self :: assertSame (2 , count ($ connection ->getQueryLog ()));
118
182
$ connection ->flushQueryLog ();
119
183
120
184
// Max
121
- $ results = EloquentWithCountModel1 ::withMax ([
185
+ $ results = EloquentWithAggregateModel1 ::withMax ([
122
186
'twos ' => function ($ query ) {
123
187
$ query ->where ('value ' , '>= ' , 2 );
124
188
},
125
189
], 'value ' );
126
190
127
- $ this -> assertSame ([
191
+ self :: assertSameResults ([
128
192
['id ' => 1 , 'twos_max ' => 3 ],
129
193
['id ' => 2 , 'twos_max ' => null ],
130
194
['id ' => 3 , 'twos_max ' => 2 ],
131
195
['id ' => 4 , 'twos_max ' => null ],
132
- ], $ results ->get ()-> toArray () );
196
+ ], $ results ->get ());
133
197
134
- $ this -> assertSame (2 , count ($ connection ->getQueryLog ()));
198
+ self :: assertSame (2 , count ($ connection ->getQueryLog ()));
135
199
$ connection ->flushQueryLog ();
136
200
137
201
// Min
138
- $ results = EloquentWithCountModel1 ::withMin ([
202
+ $ results = EloquentWithAggregateModel1 ::withMin ([
139
203
'twos ' => function ($ query ) {
140
204
$ query ->where ('value ' , '>= ' , 2 );
141
205
},
142
206
], 'value ' );
143
207
144
- $ this -> assertSame ([
208
+ self :: assertSameResults ([
145
209
['id ' => 1 , 'twos_min ' => 2 ],
146
210
['id ' => 2 , 'twos_min ' => null ],
147
211
['id ' => 3 , 'twos_min ' => 2 ],
148
212
['id ' => 4 , 'twos_min ' => null ],
149
- ], $ results ->get ()-> toArray () );
213
+ ], $ results ->get ());
150
214
151
- $ this -> assertSame (2 , count ($ connection ->getQueryLog ()));
215
+ self :: assertSame (2 , count ($ connection ->getQueryLog ()));
152
216
$ connection ->flushQueryLog ();
153
217
154
218
// Avg
155
- $ results = EloquentWithCountModel1 ::withAvg ([
219
+ $ results = EloquentWithAggregateModel1 ::withAvg ([
156
220
'twos ' => function ($ query ) {
157
221
$ query ->where ('value ' , '>= ' , 2 );
158
222
},
159
223
], 'value ' );
160
224
161
- $ this -> assertSame ([
225
+ self :: assertSameResults ([
162
226
['id ' => 1 , 'twos_avg ' => 2.5 ],
163
227
['id ' => 2 , 'twos_avg ' => null ],
164
228
['id ' => 3 , 'twos_avg ' => 2.0 ],
165
229
['id ' => 4 , 'twos_avg ' => null ],
166
- ], $ results ->get ()-> toArray () );
230
+ ], $ results ->get ());
167
231
168
- $ this -> assertSame (2 , count ($ connection ->getQueryLog ()));
232
+ self :: assertSame (2 , count ($ connection ->getQueryLog ()));
169
233
$ connection ->flushQueryLog ();
170
234
}
171
235
172
236
public function testGlobalScopes ()
173
237
{
174
- $ one = EloquentWithCountModel1 ::create ();
238
+ $ one = EloquentWithAggregateModel1 ::create ();
175
239
$ one ->fours ()->create ();
176
240
177
- $ result = EloquentWithCountModel1::withCount ('fours ' )->first ();
178
- $ this ->assertSame (0 , $ result ->fours_count );
241
+ $ result = EloquentWithAggregateModel1::withCount ('fours ' )->first ();
242
+ self ::assertSame (0 , $ result ->fours_count );
243
+
244
+ $ result = EloquentWithAggregateModel1::withCount ('allFours ' )->first ();
245
+ self ::assertSame (1 , $ result ->all_fours_count );
246
+ }
247
+
248
+ private static function assertSameResults (array $ expected , Collection $ collection )
249
+ {
250
+ $ actual = $ collection ->toArray ();
251
+
252
+ foreach ($ actual as &$ item ) {
253
+ ksort ($ item );
254
+ }
255
+
256
+ foreach ($ expected as &$ item ) {
257
+ ksort ($ item );
258
+ }
179
259
180
- $ result = EloquentWithCountModel1::withCount ('allFours ' )->first ();
181
- $ this ->assertSame (1 , $ result ->all_fours_count );
260
+ self ::assertSame ($ expected , $ actual );
182
261
}
183
262
}
184
263
185
- class EloquentWithCountModel1 extends Model
264
+ class EloquentWithAggregateModel1 extends Model
186
265
{
187
266
protected $ connection = 'mongodb ' ;
188
267
public $ table = 'one ' ;
@@ -191,21 +270,26 @@ class EloquentWithCountModel1 extends Model
191
270
192
271
public function twos ()
193
272
{
194
- return $ this ->hasMany (EloquentWithCountModel2 ::class, 'one_id ' );
273
+ return $ this ->hasMany (EloquentWithAggregateModel2 ::class, 'one_id ' );
195
274
}
196
275
197
276
public function fours ()
198
277
{
199
- return $ this ->hasMany (EloquentWithCountModel4 ::class, 'one_id ' );
278
+ return $ this ->hasMany (EloquentWithAggregateModel4 ::class, 'one_id ' );
200
279
}
201
280
202
281
public function allFours ()
203
282
{
204
283
return $ this ->fours ()->withoutGlobalScopes ();
205
284
}
285
+
286
+ public function embeddeds ()
287
+ {
288
+ return $ this ->embedsMany (EloquentWithAggregateEmbeddedModel::class);
289
+ }
206
290
}
207
291
208
- class EloquentWithCountModel2 extends Model
292
+ class EloquentWithAggregateModel2 extends Model
209
293
{
210
294
protected $ connection = 'mongodb ' ;
211
295
public $ table = 'two ' ;
@@ -224,11 +308,11 @@ protected static function boot()
224
308
225
309
public function threes ()
226
310
{
227
- return $ this ->hasMany (EloquentWithCountModel3 ::class, 'two_id ' );
311
+ return $ this ->hasMany (EloquentWithAggregateModel3 ::class, 'two_id ' );
228
312
}
229
313
}
230
314
231
- class EloquentWithCountModel3 extends Model
315
+ class EloquentWithAggregateModel3 extends Model
232
316
{
233
317
protected $ connection = 'mongodb ' ;
234
318
public $ table = 'three ' ;
@@ -245,7 +329,7 @@ protected static function boot()
245
329
}
246
330
}
247
331
248
- class EloquentWithCountModel4 extends Model
332
+ class EloquentWithAggregateModel4 extends Model
249
333
{
250
334
protected $ connection = 'mongodb ' ;
251
335
public $ table = 'four ' ;
@@ -261,3 +345,10 @@ protected static function boot()
261
345
});
262
346
}
263
347
}
348
+
349
+ class EloquentWithAggregateEmbeddedModel extends Model
350
+ {
351
+ protected $ connection = 'mongodb ' ;
352
+ public $ timestamps = false ;
353
+ protected $ guarded = [];
354
+ }
0 commit comments