Passed
Push — trunk ( 05c644...7dd39b )
by Christian
10:24 queued 14s
created

IndexCreator::indexExists()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace Shopware\Elasticsearch\Framework\Indexing;
4
5
use OpenSearch\Client;
6
use Psr\EventDispatcher\EventDispatcherInterface;
7
use Shopware\Core\Framework\Context;
8
use Shopware\Core\Framework\Log\Package;
9
use Shopware\Elasticsearch\Framework\AbstractElasticsearchDefinition;
10
use Shopware\Elasticsearch\Framework\Indexing\Event\ElasticsearchIndexConfigEvent;
11
use Shopware\Elasticsearch\Framework\Indexing\Event\ElasticsearchIndexCreatedEvent;
12
13
#[Package('core')]
14
class IndexCreator
15
{
16
    /**
17
     * @var array<mixed>
18
     */
19
    private readonly array $config;
20
21
    /**
22
     * @internal
23
     *
24
     * @param array<mixed> $config
25
     * @param array<mixed> $mapping
26
     */
27
    public function __construct(
28
        private readonly Client $client,
29
        array $config,
30
        private readonly array $mapping,
31
        private readonly EventDispatcherInterface $eventDispatcher
32
    ) {
33
        if (isset($config['settings']['index'])) {
34
            if (\array_key_exists('number_of_shards', $config['settings']['index']) && $config['settings']['index']['number_of_shards'] === null) {
35
                unset($config['settings']['index']['number_of_shards']);
36
            }
37
38
            if (\array_key_exists('number_of_replicas', $config['settings']['index']) && $config['settings']['index']['number_of_replicas'] === null) {
39
                unset($config['settings']['index']['number_of_replicas']);
40
            }
41
        }
42
43
        $this->config = $config;
0 ignored issues
show
Bug introduced by
The property config is declared read-only in Shopware\Elasticsearch\F...k\Indexing\IndexCreator.
Loading history...
44
    }
45
46
    public function createIndex(AbstractElasticsearchDefinition $definition, string $index, string $alias, Context $context): void
47
    {
48
        // NEXT-21735 - does not execute if there's no index yet
49
        // @codeCoverageIgnoreStart
50
        if ($this->client->indices()->exists(['index' => $index])) {
51
            $this->client->indices()->delete(['index' => $index]);
52
        }
53
        // @codeCoverageIgnoreEnd
54
55
        $mapping = $definition->getMapping($context);
56
57
        $mapping = $this->addFullText($mapping);
58
59
        $mapping = array_merge_recursive($mapping, $this->mapping);
60
61
        $body = array_merge(
62
            $this->config,
63
            ['mappings' => $mapping]
64
        );
65
66
        $event = new ElasticsearchIndexConfigEvent($index, $body, $definition, $context);
67
        $this->eventDispatcher->dispatch($event);
68
69
        $this->client->indices()->create([
70
            'index' => $index,
71
            'body' => $event->getConfig(),
72
        ]);
73
74
        $this->createAliasIfNotExisting($index, $alias);
75
76
        $this->eventDispatcher->dispatch(new ElasticsearchIndexCreatedEvent($index, $definition));
77
    }
78
79
    public function aliasExists(string $alias): bool
80
    {
81
        return $this->client->indices()->existsAlias(['name' => $alias]);
82
    }
83
84
    /**
85
     * @param array<mixed> $mapping
86
     *
87
     * @return array<mixed>
88
     */
89
    private function addFullText(array $mapping): array
90
    {
91
        $mapping['properties']['fullText'] = [
92
            'type' => 'text',
93
            'fields' => [
94
                'ngram' => ['type' => 'text', 'analyzer' => 'sw_ngram_analyzer'],
95
            ],
96
        ];
97
98
        $mapping['properties']['fullTextBoosted'] = ['type' => 'text'];
99
100
        if (!\array_key_exists('_source', $mapping) || !\array_key_exists('includes', $mapping['_source'])) {
101
            return $mapping;
102
        }
103
104
        $mapping['_source']['includes'][] = 'fullText';
105
        $mapping['_source']['includes'][] = 'fullTextBoosted';
106
107
        return $mapping;
108
    }
109
110
    private function createAliasIfNotExisting(string $index, string $alias): void
111
    {
112
        $exist = $this->client->indices()->existsAlias(['name' => $alias]);
113
114
        if ($exist) {
115
            return;
116
        }
117
118
        $this->client->indices()->refresh([
119
            'index' => $index,
120
        ]);
121
122
        $this->client->indices()->putAlias(['index' => $index, 'name' => $alias]);
123
    }
124
}
125