ElasticsearchService::bulkCreate()   A
last analyzed

Complexity

Conditions 4
Paths 5

Size

Total Lines 25
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 14
nc 5
nop 3
dl 0
loc 25
rs 9.7998
c 0
b 0
f 0
1
<?php
2
3
namespace Locastic\Loggastic\Bridge\Elasticsearch;
4
5
use Locastic\Loggastic\Bridge\Elasticsearch\Context\Traits\ElasticNormalizationContextTrait;
6
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
7
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
8
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
9
10
final class ElasticsearchService
11
{
12
    use ElasticNormalizationContextTrait;
13
14
    public function __construct(private readonly ElasticsearchClient $elasticsearchClient, private readonly NormalizerInterface $normalizer, private readonly DenormalizerInterface $denormalizer)
15
    {
16
    }
17
18
    public function createItem($item, string $index, array $groups = []): void
19
    {
20
        $body = $this->normalizer->normalize($item, 'array', $this->getNormalizationContext($groups));
21
22
        $request = [
23
            'index' => $index,
24
            'body' => $body,
25
            'refresh' => true,
26
        ];
27
28
        $this->elasticsearchClient->getClient()->index($request);
29
    }
30
31
    public function bulkCreate(array $items, string $index, array $groups = []): void
32
    {
33
        $params = [];
34
        foreach ($items as $i => $item) {
35
            if (0 === $i % 100) {
36
                echo '.';
37
            }
38
39
            $normalizedItem = $this->normalizer->normalize($item, 'array', $this->getNormalizationContext($groups));
40
41
            $params[] = [
42
                'index' => [
43
                    '_index' => $index,
44
                    '_id' => method_exists($item, 'getId')? $item->getId() : null,
45
                ],
46
            ];
47
            $params[] = $normalizedItem;
48
        }
49
50
        $request = [
51
            'index' => $index,
52
            'body' => $params,
53
        ];
54
55
        $this->elasticsearchClient->getClient()->bulk($request);
56
    }
57
58
    public function getItemById($id, string $index, string $denormalizeToClass): mixed
59
    {
60
        $documents = $this->elasticsearchClient->getClient()->search([
61
            'index' => $index,
62
            'body' => ['query' => ['term' => ['id' => $id]]],
63
        ]);
64
65
        if (1 !== $documents['hits']['total']) {
66
            return null;
67
        }
68
69
        $data = $documents['hits']['hits'][0]['_source'];
70
        $data['id'] = $documents['hits']['hits'][0]['_id'];
71
72
        return $this->denormalizer->denormalize($data, $denormalizeToClass);
73
    }
74
75
    public function getItemByQuery(string $index, string $denormalizeToClass, array $body = []): mixed
76
    {
77
        $documents = $this->elasticsearchClient->getClient()->search([
78
            'index' => $index,
79
            'body' => $body,
80
        ]);
81
82
        if (1 !== $documents['hits']['total']['value']) {
83
            return null;
84
        }
85
86
        $data = $documents['hits']['hits'][0]['_source'];
87
        $data['id'] = $documents['hits']['hits'][0]['_id'];
88
89
        return $this->denormalizer->denormalize($data, $denormalizeToClass, 'array');
90
    }
91
92
    public function updateItem($id, $item, string $index, array $groups = []): void
93
    {
94
        $body = $this->normalizer->normalize($item, 'array', $this->getNormalizationContext($groups));
95
96
        $request = [
97
            'index' => $index,
98
            'id' => (string) $id,
99
            'body' => ['doc' => $body],
100
            'refresh' => true,
101
            'retry_on_conflict' => 1,
102
        ];
103
104
        $this->elasticsearchClient->getClient()->update($request);
105
    }
106
107
    public function getCollection(string $index, string $denormalizeToClass, array $body = [], $limit = 20, $offset = 0): array
108
    {
109
        $documents = $this->elasticsearchClient->getClient()->search([
110
            'index' => $index,
111
            'from' => $offset,
112
            'size' => $limit,
113
            'body' => $body,
114
        ]);
115
116
        $results = [];
117
        foreach ($documents['hits']['hits'] as $document) {
118
            $document['_source']['id'] = $document['_id'];
119
            $results[] = $this->denormalizer->denormalize($document['_source'], $denormalizeToClass, 'elasticsearch', [AbstractNormalizer::ALLOW_EXTRA_ATTRIBUTES => true]);
120
        }
121
122
        return $results;
123
    }
124
}
125