Completed
Pull Request — develop (#125)
by Sam
04:00
created

IndexCommand::getProgressBarRedrawFrequency()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
eloc 1
nc 1
nop 0
1
<?php namespace Nord\Lumen\Elasticsearch\Console;
2
3
use Nord\Lumen\Elasticsearch\Documents\Bulk\BulkAction;
4
use Nord\Lumen\Elasticsearch\Documents\Bulk\BulkQuery;
5
use Nord\Lumen\Elasticsearch\Documents\Bulk\BulkResponseAggregator;
6
7
abstract class IndexCommand extends AbstractCommand
8
{
9
10
    /**
11
     * The number of items to process before updating the progress bar
12
     */
13
    const PROGRESS_BAR_REDRAW_FREQUENCY = 50;
14
15
    /**
16
     * @return array
17
     */
18
    abstract public function getData();
19
20
    /**
21
     * @return string
22
     */
23
    abstract public function getIndex();
24
25
    /**
26
     * @return string
27
     */
28
    abstract public function getType();
29
30
    /**
31
     * @param mixed $item
32
     *
33
     * @return array
34
     */
35
    abstract public function getItemBody($item);
36
37
    /**
38
     * @param mixed $item
39
     *
40
     * @return string
41
     */
42
    abstract public function getItemId($item);
43
44
    /**
45
     * @param mixed $item
46
     *
47
     * @return string
48
     */
49
    abstract public function getItemParent($item);
50
51
    /**
52
     * @inheritdoc
53
     */
54
    public function handle()
55
    {
56
        $this->indexData($this->getIndex());
57
    }
58
59
    /**
60
     * @param string $indexName
61
     */
62
    protected function indexData(string $indexName): void
63
    {
64
        $this->info(sprintf('Indexing data of type "%s" into "%s"', $this->getType(), $indexName));
65
66
        $data = $this->getData();
67
68
        $bar = $this->output->createProgressBar($this->getCount());
69
        $bar->setRedrawFrequency($this->getProgressBarRedrawFrequency());
70
71
        $bulkQuery              = new BulkQuery($this->getBulkSize());
72
        $bulkResponseAggregator = new BulkResponseAggregator();
73
74
        foreach ($data as $item) {
75
            $action = new BulkAction();
76
77
            $meta = [
78
                '_index' => $indexName,
79
                '_type'  => $this->getType(),
80
                '_id'    => $this->getItemId($item),
81
            ];
82
83
            if (($parent = $this->getItemParent($item)) !== null) {
84
                $meta['_parent'] = $parent;
85
            }
86
87
            $action->setAction(BulkAction::ACTION_INDEX, $meta)
88
                   ->setBody($this->getItemBody($item));
89
90
            $bulkQuery->addAction($action);
91
92
            if ($bulkQuery->isReady()) {
93
                $response = $this->elasticsearchService->bulk($bulkQuery->toArray());
94
                $bulkQuery->reset();
95
                $bulkResponseAggregator->addResponse($response);
96
            }
97
98
            $bar->advance();
99
        }
100
101
        if ($bulkQuery->hasItems()) {
102
            $response = $this->elasticsearchService->bulk($bulkQuery->toArray());
103
            $bulkResponseAggregator->addResponse($response);
104
        }
105
106
        $bar->finish();
107
108
        $hasErrors = $bulkResponseAggregator->hasErrors();
109
        if ($hasErrors) {
110
            $this->info("\n");
111
            $errors = $bulkResponseAggregator->getErrors();
112
            foreach ($errors as $error) {
113
                $this->error($error);
114
            }
115
        }
116
117
        $this->info("\nDone!");
118
    }
119
120
    /**
121
     * @return int the bulk size (for bulk indexing)
122
     */
123
    protected function getBulkSize()
124
    {
125
        return BulkQuery::BULK_SIZE_DEFAULT;
126
    }
127
128
    /**
129
     * @return int the progress bar redraw frequency
130
     */
131
    protected function getProgressBarRedrawFrequency()
132
    {
133
        return self::PROGRESS_BAR_REDRAW_FREQUENCY;
134
    }
135
136
    /**
137
     * Get the total count.
138
     *
139
     * @return int
140
     */
141
    protected function getCount()
142
    {
143
        return count($this->getData());
144
    }
145
}
146