Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
Total | |
0.00% |
0 / 1 |
|
0.00% |
0 / 10 |
CRAP | |
0.00% |
0 / 46 |
BaseCommand | |
0.00% |
0 / 1 |
|
0.00% |
0 / 10 |
210 | |
0.00% |
0 / 46 |
__construct | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 3 |
|||
getJsData | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 4 |
|||
launch | |
0.00% |
0 / 1 |
6 | |
0.00% |
0 / 5 |
|||
executeFile | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 4 |
|||
createExecutor | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 3 |
|||
process | |
0.00% |
0 / 1 |
20 | |
0.00% |
0 / 12 |
|||
sendChunk | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 8 |
|||
normalizeChunk | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 1 |
|||
disable | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 5 |
|||
js | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 1 |
1 | <?php |
2 | |
3 | namespace Qmp\Laravel\Deduplication\Console\Commands; |
4 | |
5 | use Illuminate\Support\Collection; |
6 | |
7 | |
8 | use Qmp\Laravel\Deduplication\Models\SessionData; |
9 | use Qmp\Laravel\ToolsLaravel\Traits\Timer; |
10 | use MongoDB\Driver\WriteConcern; |
11 | use Qmp\Laravel\MongoJsExecutor\Executor; |
12 | |
13 | abstract class BaseCommand extends TryCatchCommand |
14 | { |
15 | use Timer; |
16 | |
17 | /** |
18 | * The chunk size to send to mongo |
19 | */ |
20 | const CHUNK_SIZE = 25000; |
21 | |
22 | /** |
23 | * Undocumented variable |
24 | * |
25 | * @var array |
26 | */ |
27 | protected $falseMessage = [ |
28 | 'id' => 0, |
29 | 'message' => '' |
30 | ]; |
31 | |
32 | /** |
33 | * The aggreagtion result |
34 | * |
35 | * @var mixed |
36 | */ |
37 | protected $aggregationResult; |
38 | |
39 | /** |
40 | * The chunk collection that holds hashs |
41 | * |
42 | * @var \Illuminate\Support\Collection |
43 | */ |
44 | protected $chunk; |
45 | |
46 | /** |
47 | * The count of all hashs |
48 | * |
49 | * @var integer |
50 | */ |
51 | protected $count = 0; |
52 | |
53 | /** |
54 | * If there is no process after aggregation. |
55 | * |
56 | * @var boolean |
57 | */ |
58 | protected $onlyAggregation = false; |
59 | |
60 | /** |
61 | * Undocumented variable |
62 | * |
63 | * @var array |
64 | */ |
65 | protected $jsFiles = []; |
66 | |
67 | /** |
68 | * Undocumented variable |
69 | * |
70 | * @var array |
71 | */ |
72 | protected $extraJsData = []; |
73 | |
74 | /** |
75 | * Undocumented variable |
76 | * |
77 | * @var array |
78 | */ |
79 | protected $executorOptions = ['allowDiskUse' => true]; |
80 | |
81 | /** |
82 | * Create a new command instance. |
83 | * |
84 | * @return void |
85 | */ |
86 | public function __construct() |
87 | { |
88 | parent::__construct(); |
89 | $this->chunk = collect(); |
90 | } |
91 | |
92 | |
93 | /** |
94 | * Undocumented function |
95 | * |
96 | * @return void |
97 | */ |
98 | protected function getJsData() |
99 | { |
100 | return array_merge([ |
101 | 'sessionId' => $this->argument('sessionId'), |
102 | 'outCollection' => 'sessions_data_temp_' . $this->argument('sessionId') |
103 | ], $this->extraJsData); |
104 | } |
105 | |
106 | |
107 | /** |
108 | * The entry point of the command. |
109 | * Aggregate and process |
110 | * |
111 | * @return void |
112 | */ |
113 | protected function launch() |
114 | { |
115 | $this->info($this->falseMessage['message']); |
116 | |
117 | foreach ($this->jsFiles as $key => $file) { |
118 | $this->info("Starting aggregation : $file"); |
119 | $this->executeFile($file)->process(); |
120 | } |
121 | |
122 | //$this->info("TOTAL : $this->count duplicates found !"); |
123 | } |
124 | |
125 | /** |
126 | * Undocumented function |
127 | * |
128 | * @param [type] $file |
129 | * @return self |
130 | */ |
131 | protected function executeFile($file): self |
132 | { |
133 | $this->startTimer('pass'); |
134 | $this->aggregationResult = $this->createExecutor($file, $this->argument('sessionId'))->execute($this->executorOptions); |
135 | $this->info('Aggregation time : ' . $this->getTimer('pass')); |
136 | return $this; |
137 | } |
138 | |
139 | |
140 | /** |
141 | * Undocumented function |
142 | * |
143 | * @param [type] $file |
144 | * @return void |
145 | */ |
146 | protected function createExecutor($file, $collectionSuffix = null) |
147 | { |
148 | $executor = Executor::fromJs($this->js($file), $collectionSuffix); |
149 | $executor->withData($this->getJsData()); |
150 | |
151 | return $executor; |
152 | } |
153 | |
154 | /** |
155 | * Process the aggregation result |
156 | * |
157 | * @return void |
158 | */ |
159 | protected function process(): void |
160 | { |
161 | if (!$this->onlyAggregation) { |
162 | if ($this->aggregationResult && $this->aggregationResult->count() > 0) { |
163 | $this->startTimer('processMain'); |
164 | $count = 0; |
165 | |
166 | $this->aggregationResult->chunk(self::CHUNK_SIZE)->each(function ($chunk) { |
167 | $this->sendChunk($chunk); |
168 | }); |
169 | |
170 | $count = $this->aggregationResult->count(); |
171 | $this->info($count . " duplicates found !"); |
172 | $this->info('Php execution : ' . $this->getTimer('processMain')); |
173 | } else { |
174 | $this->info("No duplicates found !"); |
175 | } |
176 | } |
177 | } |
178 | |
179 | |
180 | /** |
181 | * Disable the current chunk collection |
182 | * |
183 | * @param Collection $duplicate |
184 | * @return void |
185 | */ |
186 | protected function sendChunk(Collection $duplicate): void |
187 | { |
188 | $duplicate = $this->normalizeChunk($duplicate); |
189 | |
190 | $this->startTimer('sendChunk'); |
191 | $this->info('sending chunk : ' . $duplicate->count() . ' entries'); |
192 | |
193 | $this->disable($duplicate->toArray()); |
194 | $this->count += $duplicate->count(); |
195 | $this->chunk = collect(); |
196 | |
197 | $this->info('Chunk sent in ' . $this->getTimer('sendChunk')); |
198 | } |
199 | |
200 | /** |
201 | * Undocumented function |
202 | * |
203 | * @param Collection $chunk |
204 | * @return Collection |
205 | */ |
206 | protected function normalizeChunk(Collection $chunk): Collection |
207 | { |
208 | return $chunk->pluck('duplicates'); |
209 | } |
210 | |
211 | |
212 | // /** |
213 | // * Add an array of hash to the chunk |
214 | // * |
215 | // * @param array $array |
216 | // * @return void |
217 | // */ |
218 | // protected function addToChunk(array $array = []): void |
219 | // { |
220 | // $this->chunk = $this->chunk->merge($array); |
221 | |
222 | // if ($this->chunk->count() >= self::CHUNK_SIZE) { |
223 | // $this->sendChunk($this->chunk); |
224 | // } |
225 | // } |
226 | |
227 | /** |
228 | * Disable hash in mongo |
229 | * |
230 | * @param array $ids |
231 | * @return void |
232 | */ |
233 | protected function disable(array $ids): void |
234 | { |
235 | SessionData::whereIn('_id', $ids)->update( |
236 | [ |
237 | 'active' => false, |
238 | 'description_dedup_false' => $this->falseMessage['id'] |
239 | ], |
240 | [ |
241 | "writeConcern" => new WriteConcern(0) |
242 | ] |
243 | ); |
244 | } |
245 | |
246 | /** |
247 | * Undocumented function |
248 | * |
249 | * @param [type] $name |
250 | * @return string |
251 | */ |
252 | protected function js($name): string |
253 | { |
254 | return realpath(__DIR__ . "/../../database/query/$name.js"); |
255 | } |
256 | } |