Query::fetchAll()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 0
1
<?php namespace Bardex\Elastic;
2
3
/**
4
 * Class Query
5
 * @package Bardex\Elastic
6
 * @author Alexey Sumin <[email protected]>
7
 */
8
abstract class Query extends PrototypeQuery
9
{
10
    /**
11
     * Получить собранный elasticsearch-запрос
12
     * @return array
13
     */
14
    abstract public function getQuery();
15
16
17
    /**
18
     * Отправить запрос на конкретный endpoint elasticsearch-сервера
19
     * @param array $query
20
     * @return array
21
     */
22
    abstract protected function executeQuery(array $query);
23
24
25
    /**
26
     * Выполнить запрос к ES и вернуть результаты поиска.
27
     * @return SearchResult - возвращает набор документов
28
     */
29
    public function fetchAll()
30
    {
31
        $response = $this->fetchRaw();
32
        $result = $this->createSearchResult($response);
33
        return $result;
34
    }
35
36
37
    /**
38
     * Выполнить запрос к ES и вернуть необработанный результат (с мета-данными).
39
     * @return array возвращает необработанный ответ ES
40
     * @throws \Exception
41
     */
42
    public function fetchRaw()
43
    {
44
        // build query
45
        $query = $this->getQuery();
46
47
        // send query to elastic
48
        $start = microtime(1);
49
50
        try {
51
            $result = $this->executeQuery($query);
52
            $time = round((microtime(1) - $start) * 1000);
53
            $this->triggerSuccess($query, $result, $time);
54
            return $result;
55
        } catch (\Exception $e) {
56
            $this->triggerError($query, $e);
57
            throw $e;
58
        }
59
    }
60
61
62
    /**
63
     * Создать из ответа ES-сервера экземляр SearchResult
64
     * @param array $response
65
     * @return SearchResult
66
     */
67
    protected function createSearchResult(array $response)
68
    {
69
        $results = $this->extractDocuments($response);
70
        $total = $this->extractTotal($response);
71
        $searchResult = new SearchResult($results, $total);
72
        return $searchResult;
73
    }
74
75
    /**
76
     * Выбрать документы из ответа ES-сервера и добавить script fields.
77
     * @param array $response - ответ ES сервера.
78
     * @return array - возвращает набор документов
79
     */
80
    protected function extractDocuments(array $response)
81
    {
82
        $results = [];
83
        if (isset($response['hits']['hits'])) {
84
            foreach ($response['hits']['hits'] as $hit) {
85
                $row = $hit['_source'];
86
                if (isset($hit['fields'])) { // script fields
87
                    foreach ($hit['fields'] as $field => $data) {
88
                        if (count($data) == 1) {
89
                            $row[$field] = array_shift($data);
90
                        } else {
91
                            $row[$field] = $data;
92
                        }
93
                    }
94
                }
95
                $results[] = $row;
96
            }
97
        }
98
        return $results;
99
    }
100
101
102
    /**
103
     * Выбрать из ответа ES-сервера количество найденных документов.
104
     * @param array $response - ответ ES сервера.
105
     * @return integer - возвращает количество найденных документов.
106
     */
107
    protected function extractTotal(array $response)
108
    {
109
        $total = 0;
110
        if (isset($response['hits']['total'])) {
111
            $total = $response['hits']['total'];
112
        }
113
        return $total;
114
    }
115
116
    protected function triggerSuccess(array $query, array $response, $time)
117
    {
118
        foreach ($this->listeners as $listener) {
119
            $listener->onSuccess($query, $response, $time);
120
        }
121
    }
122
123
    protected function triggerError(array $query, \Exception $e)
124
    {
125
        foreach ($this->listeners as $listener) {
126
            $listener->onError($query, $e);
127
        }
128
    }
129
}
130