@@ -42,6 +42,20 @@ class arSolrPlugin extends QubitSearchEngine
42
42
*/
43
43
protected $ enabled = true ;
44
44
45
+ /**
46
+ * This array will be used to store documents to add in a batch.
47
+ *
48
+ * @var array
49
+ */
50
+ private $ batchAddDocs = [];
51
+
52
+ /**
53
+ * This array will be used to store documents to delete in a batch.
54
+ *
55
+ * @var array
56
+ */
57
+ private $ batchDeleteDocs = [];
58
+
45
59
/**
46
60
* Constructor.
47
61
*/
@@ -53,6 +67,10 @@ public function __construct(array $options = [])
53
67
54
68
$ this ->client = new arSolrClient ($ this ->config ['solr ' ]);
55
69
70
+ // Load batch mode configuration
71
+ $ this ->batchMode = true === $ this ->config ['batch_mode ' ];
72
+ $ this ->batchSize = $ this ->config ['batch_size ' ];
73
+
56
74
$ this ->initialize ();
57
75
}
58
76
@@ -113,6 +131,55 @@ public function flush()
113
131
$ this ->initialize ();
114
132
}
115
133
134
+ /*
135
+ * Flush batch of documents if we're in batch mode.
136
+ *
137
+ * We process additions before deletions to avoid an error due to deleting a
138
+ * document that hasn't been created yet.
139
+ */
140
+ public function flushBatch ()
141
+ {
142
+ if ($ this ->batchMode ) {
143
+ // Batch add documents, if any
144
+ if (count ($ this ->batchAddDocs ) > 0 ) {
145
+ try {
146
+ $ response = $ this ->client ->addDocuments ($ this ->batchAddDocs );
147
+
148
+ if ($ response ->error ) {
149
+ $ this ->log (var_export ($ response ->error , true ));
150
+ $ this ->log (json_encode ($ this ->batchAddDocs ));
151
+ }
152
+ } catch (Exception $ e ) {
153
+ // Clear batchAddDocs if something went wrong too
154
+ $ this ->batchAddDocs = [];
155
+
156
+ throw $ e ;
157
+ }
158
+
159
+ $ this ->batchAddDocs = [];
160
+ }
161
+
162
+ // Batch delete documents, if any
163
+ if (count ($ this ->batchDeleteDocs ) > 0 ) {
164
+ try {
165
+ $ response = $ this ->client ->deleteDocuments ($ this ->batchDeleteDocs );
166
+
167
+ if ($ response ->error ) {
168
+ $ this ->log (var_export ($ response ->error , true ));
169
+ $ this ->log (json_encode ($ this ->batchDeleteDocs ));
170
+ }
171
+ } catch (Exception $ e ) {
172
+ // Clear batchDeleteDocs if something went wrong too
173
+ $ this ->batchDeleteDocs = [];
174
+
175
+ throw $ e ;
176
+ }
177
+
178
+ $ this ->batchDeleteDocs = [];
179
+ }
180
+ }
181
+ }
182
+
116
183
/**
117
184
* Populate index.
118
185
*
@@ -185,6 +252,9 @@ public function populate($options = [])
185
252
}
186
253
}
187
254
255
+ // Add the last batch of documents
256
+ $ this ->flushBatch ();
257
+
188
258
$ this ->addAutoCompleteConfigs ();
189
259
$ this ->setAnalyzers ();
190
260
@@ -229,11 +299,56 @@ public function addDocument($data, $type)
229
299
throw new sfException ('Failed to parse id field. ' );
230
300
}
231
301
232
- $ response = $ this ->client ->addDocument ([$ type => $ data ]);
302
+ if ($ this ->batchMode ) {
303
+ // Add this document to the batch add queue
304
+ $ document = [
305
+ $ type => $ data ,
306
+ ];
307
+ array_push ($ this ->batchAddDocs , $ document );
308
+
309
+ // If we have a full batch, send additions and deletions in bulk
310
+ if (count ($ this ->batchAddDocs ) >= $ this ->batchSize ) {
311
+ $ this ->flushBatch ();
312
+ }
313
+ } else {
314
+ $ response = $ this ->client ->addDocument ([$ type => $ data ]);
315
+
316
+ if ($ response ->error ) {
317
+ $ this ->log (var_export ($ response ->error , true ));
318
+ $ this ->log (json_encode ([$ type => $ data ]));
319
+ }
320
+ }
321
+ }
322
+
323
+ public function delete ($ object )
324
+ {
325
+ if (!$ this ->enabled ) {
326
+ return ;
327
+ }
328
+
329
+ if ($ object instanceof QubitUser) {
330
+ return ;
331
+ }
332
+
333
+ if ($ this ->batchMode ) {
334
+ // The document being deleted may not have been added to the index yet (if it's
335
+ // still queued up in $this->batchAddDocs) so create a document object representing
336
+ // the document to be deleted and add this document object to the batch delete
337
+ // queue.
338
+ $ document = $ this ->client ->createDocumentWithId ($ object ->id , get_class ($ object ));
339
+
340
+ $ this ->batchDeleteDocs [] = $ document ;
233
341
234
- if ($ response ->error ) {
235
- $ this ->log (var_export ($ response ->error , true ));
236
- $ this ->log (json_encode ([$ type => $ data ]));
342
+ // If we have a full batch, send additions and deletions in bulk
343
+ if (count ($ this ->batchDeleteDocs ) >= $ this ->batchSize ) {
344
+ $ this ->flushBatch ();
345
+ }
346
+ } else {
347
+ try {
348
+ $ this ->client ->deleteById ($ object ->id , get_class ($ object ));
349
+ } catch (Exception $ e ) {
350
+ // Ignore
351
+ }
237
352
}
238
353
}
239
354
@@ -292,32 +407,36 @@ private function addAutoCompleteFields()
292
407
'QubitAip.type.i18n.%s%.name ' ,
293
408
];
294
409
410
+ $ fields = [];
411
+ $ copyFields = [];
412
+
295
413
foreach ($ this ->langs as $ lang ) {
296
- $ addFieldArr = [
414
+ $ langField = [
297
415
'name ' => "autocomplete_ {$ lang }" ,
298
416
'type ' => "text_ {$ lang }" ,
299
417
'stored ' => 'true ' ,
300
418
'multiValued ' => 'true ' ,
301
419
];
302
420
303
- $ copyFieldsArr = [
304
- [
305
- 'source ' => 'QubitInformationObject.referenceCode ' ,
306
- 'dest ' => "autocomplete_ {$ lang }" ,
307
- ],
421
+ $ refField = [
422
+ 'source ' => 'QubitInformationObject.referenceCode ' ,
423
+ 'dest ' => "autocomplete_ {$ lang }" ,
308
424
];
309
- $ this ->client ->addFields ($ addFieldArr );
425
+
426
+ array_push ($ fields , $ langField );
427
+ array_push ($ copyFields , $ refField );
310
428
311
429
foreach ($ autocompleteFields as $ field ) {
312
430
$ field = str_replace ('%s% ' , $ lang , $ field );
313
- array_push ($ copyFieldsArr , [
431
+ array_push ($ copyFields , [
314
432
'source ' => $ field ,
315
433
'dest ' => "autocomplete_ {$ lang }" ,
316
434
]);
317
435
}
318
-
319
- $ this ->client ->addCopyFields ($ copyFieldsArr );
320
436
}
437
+
438
+ $ this ->client ->addFields ($ fields );
439
+ $ this ->client ->addCopyFields ($ copyFields );
321
440
}
322
441
323
442
private function addAutoCompleteConfigs ()
0 commit comments