|
4 | 4 |
|
5 | 5 | use Illuminate\Support\Facades\DB; |
6 | 6 | use PDPhilip\Elasticsearch\Tests\Models\Item; |
7 | | -use PDPhilip\Elasticsearch\Tests\Models\User; |
8 | 7 |
|
9 | 8 | beforeEach(function () { |
10 | | - User::executeSchema(); |
11 | 9 | Item::executeSchema(); |
12 | 10 |
|
13 | 11 | DB::table('items')->insert([ |
14 | | - ['name' => 'sword alpha', 'type' => 'sharp', 'amount' => 1500, 'stock' => 1], |
15 | | - ['name' => 'sword beta', 'type' => 'sharp', 'amount' => 900, 'stock' => 10], |
16 | | - ['name' => 'teddy', 'type' => 'fluffy', 'amount' => 10, 'stock' => 5], |
17 | | - ['name' => 'spoon', 'type' => 'round', 'amount' => 3, 'stock' => 15], |
18 | | - ['name' => 'sword charlie', 'type' => 'sharp', 'amount' => 350, 'stock' => 111], |
19 | | - ['name' => 'sword delta', 'type' => 'sharp', 'amount' => 99, 'stock' => 12], |
20 | | - ['name' => 'knife', 'type' => 'sharp', 'amount' => 8, 'stock' => 1], |
21 | | - ['name' => 'fork', 'type' => 'sharp', 'amount' => 6, 'stock' => 5], |
22 | | - ['name' => 'golf ball', 'type' => 'round', 'amount' => 14, 'stock' => 7], |
23 | | - ['name' => 'ball', 'type' => 'round', 'amount' => 14, 'stock' => 7], |
| 12 | + ['name' => 'sword alpha', 'type' => 'sharp', 'price' => 1500, 'stock' => 1, 'last_sale_at' => '2024-01-01'], |
| 13 | + ['name' => 'sword beta', 'type' => 'sharp', 'price' => 900, 'stock' => 10, 'last_sale_at' => '2024-02-01'], |
| 14 | + ['name' => 'teddy', 'type' => 'fluffy', 'price' => 10, 'stock' => 5, 'last_sale_at' => '2024-03-01'], |
| 15 | + ['name' => 'spoon', 'type' => 'round', 'price' => 3, 'stock' => 15, 'last_sale_at' => '2024-04-01'], |
| 16 | + ['name' => 'sword charlie', 'type' => 'sharp', 'price' => 350, 'stock' => 111, 'last_sale_at' => '2024-05-01'], |
| 17 | + ['name' => 'sword delta', 'type' => 'sharp', 'price' => 99, 'stock' => 12, 'last_sale_at' => '2024-06-01'], |
| 18 | + ['name' => 'knife', 'type' => 'sharp', 'price' => 8, 'stock' => 1, 'last_sale_at' => '2024-07-01'], |
| 19 | + ['name' => 'fork', 'type' => 'sharp', 'price' => 6, 'stock' => 5, 'last_sale_at' => '2024-08-01'], |
| 20 | + ['name' => 'golf ball', 'type' => 'round', 'price' => 14, 'stock' => 7, 'last_sale_at' => '2024-09-01'], |
| 21 | + ['name' => 'ball', 'type' => 'round', 'price' => 14, 'stock' => 7, 'last_sale_at' => '2024-10-01'], |
24 | 22 | ]); |
25 | 23 |
|
26 | 24 | }); |
|
33 | 31 | [15, null], |
34 | 32 | ])->get(); |
35 | 33 | expect($groups)->toHaveCount(3) |
36 | | - ->and($groups[0]['key'])->toBe('*-5.0') |
37 | | - ->and($groups[1]['key'])->toBe('5.0-15.0') |
38 | | - ->and($groups[2]['key'])->toBe('15.0-*') |
39 | | - ->and($groups[0]['count'])->toBe(2) |
40 | | - ->and($groups[1]['count'])->toBe(6) |
41 | | - ->and($groups[2]['count'])->toBe(2); |
| 34 | + ->and($groups[0]['count_stock_range_*-5.0'])->toBe(2) |
| 35 | + ->and($groups[1]['count_stock_range_5.0-15.0'])->toBe(6) |
| 36 | + ->and($groups[2]['count_stock_range_15.0-*'])->toBe(2); |
42 | 37 |
|
43 | 38 | }); |
44 | 39 | it('groups by ranges using associative arrays for ranges', function () { |
|
56 | 51 | ], |
57 | 52 | ])->get(); |
58 | 53 | expect($groups)->toHaveCount(3) |
59 | | - ->and($groups[0]['key'])->toBe('*-5.0') |
60 | | - ->and($groups[1]['key'])->toBe('5.0-15.0') |
61 | | - ->and($groups[2]['key'])->toBe('15.0-*') |
62 | | - ->and($groups[0]['count'])->toBe(2) |
63 | | - ->and($groups[1]['count'])->toBe(6) |
64 | | - ->and($groups[2]['count'])->toBe(2); |
| 54 | + ->and($groups[0]['count_stock_range_*-5.0'])->toBe(2) |
| 55 | + ->and($groups[1]['count_stock_range_5.0-15.0'])->toBe(6) |
| 56 | + ->and($groups[2]['count_stock_range_15.0-*'])->toBe(2); |
65 | 57 | }); |
66 | 58 |
|
67 | 59 | it('groups by ranges using associative arrays for ranges with custom keys', function () { |
|
82 | 74 | ], |
83 | 75 | ])->get(); |
84 | 76 | expect($groups)->toHaveCount(3) |
85 | | - ->and($groups[0]['key'])->toBe('low-stock') |
86 | | - ->and($groups[1]['key'])->toBe('medium-stock') |
87 | | - ->and($groups[2]['key'])->toBe('high-stock') |
88 | | - ->and($groups[0]['count'])->toBe(2) |
89 | | - ->and($groups[1]['count'])->toBe(6) |
90 | | - ->and($groups[2]['count'])->toBe(2); |
| 77 | + ->and($groups[0]['count_stock_range_low-stock'])->toBe(2) |
| 78 | + ->and($groups[1]['count_stock_range_medium-stock'])->toBe(6) |
| 79 | + ->and($groups[2]['count_stock_range_high-stock'])->toBe(2); |
91 | 80 | }); |
92 | 81 |
|
93 | 82 | it('groups by ranges and aggregates', function () { |
|
106 | 95 | 'key' => 'high-stock', |
107 | 96 | 'from' => 15, |
108 | 97 | ], |
109 | | - ])->agg(['min', 'max', 'count'], 'amount'); |
| 98 | + ])->agg(['min', 'max', 'count'], 'price'); |
110 | 99 | expect($groups)->toHaveCount(3) |
111 | | - ->and($groups[1]['key'])->toBe('medium-stock') |
112 | | - ->and($groups[1]['count'])->toBe(6) |
113 | | - ->and($groups[1]['count'])->toBe($groups[1]['count_amount']) // the aggregate `count_amount` reflects the same as the group count |
114 | | - ->and((int) $groups[1]['min_amount'])->toBe(6) |
115 | | - ->and((int) $groups[1]['max_amount'])->toBe(900); |
| 100 | + ->and($groups[1]['count_stock_range_medium-stock'])->toBe(6) |
| 101 | + ->and($groups[1]['count_stock_range_medium-stock'])->toBe($groups[1]['count_price_stock_range_medium-stock']) // the aggregate `count_amount` reflects the same as the group count |
| 102 | + ->and((int) $groups[1]['min_price_stock_range_medium-stock'])->toBe(6) |
| 103 | + ->and((int) $groups[1]['max_price_stock_range_medium-stock'])->toBe(900); |
| 104 | +}); |
| 105 | + |
| 106 | +it('groups by ranges and aggregates with original bucket in meta', function () { |
| 107 | + |
| 108 | + $groups = Item::groupByRanges('stock', [ |
| 109 | + [ |
| 110 | + 'key' => 'low-stock', |
| 111 | + 'to' => 5, |
| 112 | + ], |
| 113 | + [ |
| 114 | + 'key' => 'medium-stock', |
| 115 | + 'from' => 5, |
| 116 | + 'to' => 15, |
| 117 | + ], |
| 118 | + [ |
| 119 | + 'key' => 'high-stock', |
| 120 | + 'from' => 15, |
| 121 | + ], |
| 122 | + ])->agg(['min', 'max', 'count'], 'price'); |
| 123 | + $bucketMediumStock = $groups[1]->getMetaValue('bucket'); |
| 124 | + expect($bucketMediumStock)->toHaveCount(7) |
| 125 | + ->and($bucketMediumStock['key'])->toBe('medium-stock') |
| 126 | + ->and((int) $bucketMediumStock['from'])->toBe(5) |
| 127 | + ->and((int) $bucketMediumStock['to'])->toBe(15) |
| 128 | + ->and((int) $bucketMediumStock['doc_count'])->toBe(6) |
| 129 | + ->and((int) $bucketMediumStock['count_price']['value'])->toBe(6) |
| 130 | + ->and((int) $bucketMediumStock['min_price']['value'])->toBe(6) |
| 131 | + ->and((int) $bucketMediumStock['max_price']['value'])->toBe(900); |
| 132 | +}); |
| 133 | + |
| 134 | +it('groups by date range and aggregates', function () { |
| 135 | + |
| 136 | + $ranges = [ |
| 137 | + ['to' => '2024-05-01', 'key' => 'before-campaign'], |
| 138 | + ['from' => '2024-05-01', 'key' => 'after-campaign'], |
| 139 | + ]; |
| 140 | + $options = ['format' => 'yyyy-MM-dd']; |
| 141 | + $groups = Item::groupByDateRanges('last_sale_at', $ranges, $options)->agg(['min', 'max', 'count'], 'price'); |
| 142 | + expect($groups)->toHaveCount(2) |
| 143 | + ->and((int) $groups[0]['count_last_sale_at_range_before-campaign'])->toBe(4) |
| 144 | + ->and((int) $groups[0]['min_price_last_sale_at_range_before-campaign'])->toBe(3) |
| 145 | + ->and((int) $groups[0]['max_price_last_sale_at_range_before-campaign'])->toBe(1500) |
| 146 | + ->and((int) $groups[0]['count_price_last_sale_at_range_before-campaign'])->toBe(4) |
| 147 | + ->and((int) $groups[1]['count_last_sale_at_range_after-campaign'])->toBe(6) |
| 148 | + ->and((int) $groups[1]['min_price_last_sale_at_range_after-campaign'])->toBe(6) |
| 149 | + ->and((int) $groups[1]['max_price_last_sale_at_range_after-campaign'])->toBe(350) |
| 150 | + ->and((int) $groups[1]['count_price_last_sale_at_range_after-campaign'])->toBe(6); |
116 | 151 | }); |
0 commit comments