Skip to content

Commit 11437b6

Browse files
committed
Create QueryBuilderDistinctAggregationTest.php
1 parent 1056aea commit 11437b6

1 file changed

Lines changed: 157 additions & 0 deletions

File tree

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use Illuminate\Support\Facades\DB;
6+
use PDPhilip\Elasticsearch\Tests\Models\Item;
7+
use PDPhilip\Elasticsearch\Tests\Models\User;
8+
9+
beforeEach(function () {
10+
User::executeSchema();
11+
Item::executeSchema();
12+
});
13+
14+
it('aggregates distinct value, ordered by _count desc [ES default]', function () {
15+
16+
DB::table('items')->insert([
17+
['name' => 'sword', 'type' => 'sharp', 'amount' => 34, 'stock' => 1],
18+
['name' => 'knife', 'type' => 'sharp', 'amount' => 34, 'stock' => 1],
19+
['name' => 'fork', 'type' => 'sharp', 'amount' => 20, 'stock' => 5],
20+
['name' => 'spoon', 'type' => 'round', 'amount' => 3, 'stock' => 15],
21+
['name' => 'ball', 'type' => 'round', 'amount' => 14, 'stock' => 7],
22+
['name' => 'teddy', 'type' => 'fluffy', 'amount' => 3, 'stock' => 5],
23+
]);
24+
25+
$items = Item::distinct('type');
26+
expect($items)->toHaveCount(3)
27+
->and($items[0]['type'])->toBe('sharp')
28+
->and($items[2]['type'])->toBe('fluffy');
29+
});
30+
31+
it('aggregates distinct value, ordered by _count asc', function () {
32+
33+
DB::table('items')->insert([
34+
['name' => 'sword', 'type' => 'sharp', 'amount' => 34, 'stock' => 1],
35+
['name' => 'knife', 'type' => 'sharp', 'amount' => 34, 'stock' => 1],
36+
['name' => 'fork', 'type' => 'sharp', 'amount' => 20, 'stock' => 5],
37+
['name' => 'spoon', 'type' => 'round', 'amount' => 3, 'stock' => 15],
38+
['name' => 'ball', 'type' => 'round', 'amount' => 14, 'stock' => 7],
39+
['name' => 'teddy', 'type' => 'fluffy', 'amount' => 3, 'stock' => 5],
40+
]);
41+
42+
$items = Item::orderBy('_count')->distinct('type');
43+
expect($items)->toHaveCount(3)
44+
->and($items[0]['type'])->toBe('fluffy')
45+
->and($items[2]['type'])->toBe('sharp');
46+
47+
});
48+
49+
it('aggregates distinct value with count', function () {
50+
51+
DB::table('items')->insert([
52+
['name' => 'sword', 'type' => 'sharp', 'amount' => 34, 'stock' => 1],
53+
['name' => 'knife', 'type' => 'sharp', 'amount' => 34, 'stock' => 1],
54+
['name' => 'fork', 'type' => 'sharp', 'amount' => 20, 'stock' => 5],
55+
['name' => 'spoon', 'type' => 'round', 'amount' => 3, 'stock' => 15],
56+
['name' => 'ball', 'type' => 'round', 'amount' => 14, 'stock' => 7],
57+
['name' => 'teddy', 'type' => 'fluffy', 'amount' => 3, 'stock' => 5],
58+
]);
59+
60+
$items = Item::distinct('type', true);
61+
expect($items)->toHaveCount(3)
62+
->and($items[0]['type'])->toBe('sharp')
63+
->and($items[0]['type_count'])->toBe(3)
64+
->and($items[2]['type'])->toBe('fluffy')
65+
->and($items[2]['type_count'])->toBe(1);
66+
});
67+
68+
it('aggregates distinct values (cumulative fields), with count', function () {
69+
70+
DB::table('items')->insert([
71+
['name' => 'teddy', 'type' => 'fluffy', 'amount' => 3, 'stock' => 33],
72+
['name' => 'sword', 'type' => 'sharp', 'amount' => 34, 'stock' => 10],
73+
['name' => 'knife', 'type' => 'sharp', 'amount' => 34, 'stock' => 10],
74+
['name' => 'fork', 'type' => 'sharp', 'amount' => 20, 'stock' => 25],
75+
['name' => 'spoon', 'type' => 'round', 'amount' => 3, 'stock' => 25],
76+
['name' => 'ball', 'type' => 'round', 'amount' => 14, 'stock' => 33],
77+
78+
]);
79+
80+
$items = Item::distinct(['type', 'stock'], true);
81+
expect($items)->toHaveCount(5)
82+
->and($items[0]['type'])->toBe('sharp')
83+
->and($items[0]['stock'])->toBe(10)
84+
->and($items[0]['stock_count'])->toBe(2)
85+
->and($items[4]['type'])->toBe('fluffy')
86+
->and($items[4]['stock'])->toBe(33)
87+
->and($items[4]['stock_count'])->toBe(1);
88+
});
89+
90+
it('aggregates distinct value returning top 2 only', function () {
91+
92+
DB::table('items')->insert([
93+
['name' => 'sword alpha', 'type' => 'sharp', 'amount' => 34, 'stock' => 1],
94+
['name' => 'sword beta', 'type' => 'sharp', 'amount' => 34, 'stock' => 10],
95+
['name' => 'teddy', 'type' => 'fluffy', 'amount' => 3, 'stock' => 5],
96+
['name' => 'spoon', 'type' => 'round', 'amount' => 3, 'stock' => 15],
97+
['name' => 'sword charlie', 'type' => 'sharp', 'amount' => 34, 'stock' => 111],
98+
['name' => 'sword delta', 'type' => 'sharp', 'amount' => 34, 'stock' => 12],
99+
['name' => 'knife', 'type' => 'sharp', 'amount' => 34, 'stock' => 1],
100+
['name' => 'fork', 'type' => 'sharp', 'amount' => 20, 'stock' => 5],
101+
['name' => 'golf ball', 'type' => 'round', 'amount' => 14, 'stock' => 7],
102+
['name' => 'ball', 'type' => 'round', 'amount' => 14, 'stock' => 7],
103+
104+
]);
105+
106+
$items = Item::limit(2)->distinct('type');
107+
expect($items)->toHaveCount(2)
108+
->and($items[0]['type'])->toBe('sharp')
109+
->and($items[1]['type'])->toBe('round');
110+
});
111+
112+
it('aggregates distinct value with relations, with count', function () {
113+
114+
$user = User::create(['name' => 'John Doe']);
115+
Item::create(['type' => 'knife', 'user_id' => $user->id]);
116+
Item::create(['type' => 'shield', 'user_id' => $user->id]);
117+
118+
$user2 = User::create(['name' => 'Jane Doe']);
119+
Item::create(['type' => 'teddy', 'user_id' => $user2->id]);
120+
Item::create(['type' => 'ball', 'user_id' => $user2->id]);
121+
Item::create(['type' => 'sword', 'user_id' => $user2->id]);
122+
123+
Item::create(['type' => 'bag', 'user_id' => null]);
124+
125+
$itemUsers = Item::with('user')->distinct('user_id', true);
126+
expect($itemUsers)->not()->toHaveCount(3)
127+
->toHaveCount(2)
128+
->and($itemUsers[0]['user_id_count'])->toBe(3)
129+
->and($itemUsers[0]->user->name)->toBe('Jane Doe')
130+
->and($itemUsers[1]['user_id_count'])->toBe(2)
131+
->and($itemUsers[1]->user->name)->toBe('John Doe');
132+
});
133+
134+
it('aggregates bulk distinct values in one call, with count', function () {
135+
136+
DB::table('items')->insert([
137+
['name' => 'teddy', 'type' => 'fluffy', 'amount' => 3, 'stock' => 33],
138+
['name' => 'sword', 'type' => 'sharp', 'amount' => 34, 'stock' => 33],
139+
['name' => 'knife', 'type' => 'sharp', 'amount' => 34, 'stock' => 10],
140+
['name' => 'fork', 'type' => 'sharp', 'amount' => 20, 'stock' => 25],
141+
['name' => 'spoon', 'type' => 'round', 'amount' => 3, 'stock' => 25],
142+
['name' => 'ball', 'type' => 'round', 'amount' => 14, 'stock' => 33],
143+
144+
]);
145+
146+
$items = Item::bulkDistinct(['type', 'stock'], true);
147+
expect($items)
148+
->toHaveCount(6)
149+
->and($items[0]['type'])->toBe('sharp')
150+
->and($items[0]['type_count'])->toBe(3)
151+
->and($items[2]['type'])->toBe('fluffy')
152+
->and($items[2]['type_count'])->toBe(1)
153+
->and($items[3]['stock'])->toBe(33)
154+
->and($items[3]['stock_count'])->toBe(3)
155+
->and($items[5]['stock'])->toBe(10)
156+
->and($items[5]['stock_count'])->toBe(1);
157+
});

0 commit comments

Comments
 (0)