1 | <?php |
||
2 | declare(strict_types=1); |
||
3 | |||
4 | namespace Level23\Druid\Concerns; |
||
5 | |||
6 | use ArrayObject; |
||
7 | use Level23\Druid\Types\DataType; |
||
8 | use Level23\Druid\Dimensions\Dimension; |
||
9 | use Level23\Druid\Dimensions\LookupDimension; |
||
10 | use Level23\Druid\Dimensions\DimensionInterface; |
||
11 | use Level23\Druid\Dimensions\ListFilteredDimension; |
||
12 | use Level23\Druid\Dimensions\RegexFilteredDimension; |
||
13 | use Level23\Druid\Dimensions\PrefixFilteredDimension; |
||
14 | |||
15 | trait HasDimensions |
||
16 | { |
||
17 | /** |
||
18 | * @var array|DimensionInterface[] |
||
19 | */ |
||
20 | protected array $dimensions = []; |
||
21 | |||
22 | /** |
||
23 | * @return array|DimensionInterface[] |
||
24 | */ |
||
25 | 14 | public function getDimensions(): array |
|
26 | { |
||
27 | 14 | return $this->dimensions; |
|
28 | } |
||
29 | |||
30 | /** |
||
31 | * Select a dimension from our statistics. Possible use a lookup function to find the |
||
32 | * real data which we want to use. |
||
33 | * |
||
34 | * @param \ArrayObject<int|string,string>|string|DimensionInterface|array<int,string> $dimension |
||
35 | * @param string $as When dimensions |
||
36 | * is a string (the |
||
37 | * dimension), you |
||
38 | * can specify the |
||
39 | * alias output name |
||
40 | * here. |
||
41 | * @param string|DataType $outputType This can either |
||
42 | * be |
||
43 | * "long", |
||
44 | * "float" or |
||
45 | * "string" |
||
46 | * |
||
47 | * @return self |
||
48 | */ |
||
49 | 47 | public function select( |
|
50 | array|ArrayObject|string|DimensionInterface $dimension, |
||
51 | string $as = '', |
||
52 | string|DataType $outputType = DataType::STRING |
||
53 | ): self { |
||
54 | 47 | if (is_string($dimension)) { |
|
0 ignored issues
–
show
introduced
by
![]() |
|||
55 | 28 | $this->addDimension(new Dimension( |
|
56 | 28 | $dimension, |
|
57 | 28 | ($as ?: $dimension), |
|
58 | 28 | is_string($outputType) ? DataType::from(strtolower($outputType)) : $outputType, |
|
59 | 28 | )); |
|
60 | } else { |
||
61 | 20 | $this->addDimension($dimension); |
|
62 | } |
||
63 | |||
64 | 46 | return $this; |
|
65 | } |
||
66 | |||
67 | /** |
||
68 | * Select a dimension and transform it using a lookup function. |
||
69 | * |
||
70 | * @param string $lookupFunction The name of the registered lookup function which you want to use |
||
71 | * @param string $dimension The dimension which you want to transform using the lookup function. |
||
72 | * @param string $as The name as it will be used in the result set. If left empty, we will |
||
73 | * use the same name as the dimension. |
||
74 | * @param bool|string $keepMissingValue When true, we will keep values which are not known in the lookup |
||
75 | * function. The original value will be kept. If false, the missing items |
||
76 | * will not be kept in the result set. If this is a string, we will keep |
||
77 | * the missing values and replace them with the string value. |
||
78 | * |
||
79 | * @return self |
||
80 | */ |
||
81 | 7 | public function lookup( |
|
82 | string $lookupFunction, |
||
83 | string $dimension, |
||
84 | string $as = '', |
||
85 | bool|string $keepMissingValue = false |
||
86 | ): self { |
||
87 | 7 | $this->addDimension(new LookupDimension( |
|
88 | 7 | $dimension, |
|
89 | 7 | $lookupFunction, |
|
90 | 7 | ($as ?: $dimension), |
|
91 | 7 | $keepMissingValue |
|
92 | 7 | )); |
|
93 | |||
94 | 7 | return $this; |
|
95 | } |
||
96 | |||
97 | /** |
||
98 | * Select a dimension and transform it using the given lookup map. |
||
99 | * |
||
100 | * @param array<string,string> $map A list with key = value items, where the dimension value will be |
||
101 | * looked up in the map, and be replaced by the value in the map. |
||
102 | * @param string $dimension The dimension which you want to transform using the lookup |
||
103 | * function. |
||
104 | * @param string $as The name as it will be used in the result set. If left empty, we |
||
105 | * will use the same name as the dimension. |
||
106 | * @param bool|string $keepMissingValue When true, we will keep values which are not known in the lookup |
||
107 | * function. The original value will be kept. If false, the missing |
||
108 | * items will not be kept in the result set. If this is a string, we |
||
109 | * will keep the missing values and replace them with the string |
||
110 | * value. |
||
111 | * @param bool $isOneToOne Set to true if the key/value items are unique in the given map. |
||
112 | * |
||
113 | * @return self |
||
114 | */ |
||
115 | 1 | public function inlineLookup( |
|
116 | array $map, |
||
117 | string $dimension, |
||
118 | string $as = '', |
||
119 | bool|string $keepMissingValue = false, |
||
120 | bool $isOneToOne = false |
||
121 | ): self { |
||
122 | 1 | $this->addDimension(new LookupDimension( |
|
123 | 1 | $dimension, |
|
124 | 1 | $map, |
|
125 | 1 | ($as ?: $dimension), |
|
126 | 1 | $keepMissingValue, |
|
127 | 1 | $isOneToOne |
|
128 | 1 | )); |
|
129 | |||
130 | 1 | return $this; |
|
131 | } |
||
132 | |||
133 | /** |
||
134 | * For a multi value field, you can filter which values should be returned based in the given list. |
||
135 | * |
||
136 | * @see: https://druid.apache.org/docs/latest/querying/multi-value-dimensions.html |
||
137 | * |
||
138 | * @param string $dimension The name of the multi-value dimension where you want to select data from |
||
139 | * @param string[] $values A list of items which you want to select (whitelist) or not select |
||
140 | * (blacklist) |
||
141 | * @param string $as The name as it will be used in the result set. If left empty, we will use |
||
142 | * the same name as the dimension. |
||
143 | * @param string|DataType $outputType This can either be "long", "float" or "string" |
||
144 | * @param bool $isWhitelist Whether the list is a whitelist (true) or a blacklist (false) |
||
145 | * |
||
146 | * @return self |
||
147 | */ |
||
148 | 3 | public function multiValueListSelect( |
|
149 | string $dimension, |
||
150 | array $values, |
||
151 | string $as = '', |
||
152 | string|DataType $outputType = DataType::STRING, |
||
153 | bool $isWhitelist = true |
||
154 | ): self { |
||
155 | 3 | $this->addDimension(new ListFilteredDimension( |
|
156 | 3 | new Dimension( |
|
157 | 3 | $dimension, |
|
158 | 3 | $as ?: $dimension, |
|
159 | 3 | $outputType |
|
160 | 3 | ), |
|
161 | 3 | $values, |
|
162 | 3 | $isWhitelist |
|
163 | 3 | )); |
|
164 | |||
165 | 3 | return $this; |
|
166 | } |
||
167 | |||
168 | /** |
||
169 | * For a multi value field, you can filter which values should be returned based on the given java regular |
||
170 | * expression. |
||
171 | * |
||
172 | * @see: https://druid.apache.org/docs/latest/querying/multi-value-dimensions.html |
||
173 | * |
||
174 | * @param string $dimension The name of the multi-value dimension where you want to select data from |
||
175 | * @param string $regex Only return the items in this dimension which match with the given java |
||
176 | * regex. |
||
177 | * @param string $as The name as it will be used in the result set. If left empty, we will use the |
||
178 | * same name as the dimension. |
||
179 | * @param string|DataType $outputType This can either be "long", "float" or "string" |
||
180 | * |
||
181 | * @return self |
||
182 | */ |
||
183 | 3 | public function multiValueRegexSelect( |
|
184 | string $dimension, |
||
185 | string $regex, |
||
186 | string $as = '', |
||
187 | string|DataType $outputType = DataType::STRING |
||
188 | ): self { |
||
189 | 3 | $this->addDimension(new RegexFilteredDimension( |
|
190 | 3 | new Dimension( |
|
191 | 3 | $dimension, |
|
192 | 3 | $as ?: $dimension, |
|
193 | 3 | $outputType |
|
194 | 3 | ), |
|
195 | 3 | $regex |
|
196 | 3 | )); |
|
197 | |||
198 | 3 | return $this; |
|
199 | } |
||
200 | |||
201 | /** |
||
202 | * For a multi value field, you can filter which values should be returned based on the given prefix. |
||
203 | * |
||
204 | * @see: https://druid.apache.org/docs/latest/querying/multi-value-dimensions.html |
||
205 | * |
||
206 | * @param string $dimension The name of the multi-value dimension where you want to select data from |
||
207 | * @param string $prefix Only return the values which match with the given prefix. |
||
208 | * @param string $as The name as it will be used in the result set. If left empty, we will use the |
||
209 | * same name as the dimension. |
||
210 | * @param string|DataType $outputType This can either be "long", "float" or "string" |
||
211 | * |
||
212 | * @return self |
||
213 | */ |
||
214 | 3 | public function multiValuePrefixSelect( |
|
215 | string $dimension, |
||
216 | string $prefix, |
||
217 | string $as = '', |
||
218 | string|DataType $outputType = DataType::STRING |
||
219 | ): self { |
||
220 | 3 | $this->addDimension(new PrefixFilteredDimension( |
|
221 | 3 | new Dimension( |
|
222 | 3 | $dimension, |
|
223 | 3 | $as ?: $dimension, |
|
224 | 3 | $outputType |
|
225 | 3 | ), |
|
226 | 3 | $prefix |
|
227 | 3 | )); |
|
228 | |||
229 | 3 | return $this; |
|
230 | } |
||
231 | |||
232 | /** |
||
233 | * Add a dimension or a set of dimensions to our dimension list. |
||
234 | * |
||
235 | * @param ArrayObject<int|string,string>|string|DimensionInterface|array<int,string> $dimension |
||
236 | */ |
||
237 | 57 | protected function addDimension(array|ArrayObject|string|DimensionInterface $dimension): void |
|
238 | { |
||
239 | 57 | if ($dimension instanceof DimensionInterface) { |
|
0 ignored issues
–
show
|
|||
240 | 44 | $this->dimensions[] = $dimension; |
|
241 | 16 | } elseif (is_string($dimension)) { |
|
0 ignored issues
–
show
|
|||
242 | 4 | $this->dimensions[] = new Dimension($dimension, $dimension); |
|
243 | 16 | } elseif (is_iterable($dimension)) { |
|
244 | 16 | foreach ($dimension as $key => $value) { |
|
245 | 16 | if (is_string($key) && is_string($value)) { |
|
246 | 13 | $this->dimensions[] = new Dimension($key, $value); |
|
247 | } else { |
||
248 | 4 | $this->addDimension($value); |
|
249 | } |
||
250 | } |
||
251 | } |
||
252 | } |
||
253 | } |