Lines
0.00%
0 / 95
Methods
0.00%
0 / 13
Classes
0.00%
0 / 1
| Name | Lines | Methods | CRAP | ||||
|---|---|---|---|---|---|---|---|
| __construct | 0.00% | 0 / 6 | 0.00% | 0 / 1 | 12 | ||
| run | 0.00% | 0 / 5 | 0.00% | 0 / 1 | 2 | ||
| readTopics | 0.00% | 0 / 23 | 0.00% | 0 / 1 | 20 | ||
| readServices | 0.00% | 0 / 8 | 0.00% | 0 / 1 | 12 | ||
| readLocations | 0.00% | 0 / 8 | 0.00% | 0 / 1 | 12 | ||
| readAuthorities | 0.00% | 0 / 8 | 0.00% | 0 / 1 | 12 | ||
| getConnection | 0.00% | 0 / 7 | 0.00% | 0 / 1 | 6 | ||
| getIndex | 0.00% | 0 / 11 | 0.00% | 0 / 1 | 20 | ||
| setHost | 0.00% | 0 / 2 | 0.00% | 0 / 1 | 2 | ||
| setPort | 0.00% | 0 / 2 | 0.00% | 0 / 1 | 2 | ||
| setTransport | 0.00% | 0 / 2 | 0.00% | 0 / 1 | 2 | ||
| setAlias | 0.00% | 0 / 3 | 0.00% | 0 / 1 | 2 | ||
| dropOldIndex | 0.00% | 0 / 10 | 0.00% | 0 / 1 | 30 | ||
| 15 | class ElasticSearch | |
| 16 | { | |
| 17 | public const string ES_INDEX_PREFIX = 'dldb-'; | |
| 18 | ||
| 19 | public const string ES_INDEX_DATE = 'Ymd-His'; | |
| 20 | ||
| 21 | protected mixed $localeList = array( | |
| 22 | 'de', | |
| 23 | 'en' | |
| 24 | ); | |
| 25 | ||
| 26 | /** | |
| 27 | * Access to DLDB files | |
| 28 | * | |
| 29 | * @var FileAccess $dldb | |
| 30 | */ | |
| 31 | protected $dldb; | |
| 32 | ||
| 33 | /** | |
| 34 | * hostname for ES | |
| 35 | * | |
| 36 | * @var String $host | |
| 37 | */ | |
| 38 | protected $host = 'localhost'; | |
| 39 | ||
| 40 | /** | |
| 41 | * port for ES | |
| 42 | * | |
| 43 | * @var String $port | |
| 44 | */ | |
| 45 | protected $port = '9200'; | |
| 46 | ||
| 47 | /** | |
| 48 | * transport method for ES | |
| 49 | * | |
| 50 | * @var String $transport | |
| 51 | */ | |
| 52 | protected $transport = 'Http'; | |
| 53 | ||
| 54 | /** | |
| 55 | * The client used to talk to elastic search. | |
| 56 | * | |
| 57 | * @var \Elastica\Client|null | |
| 58 | */ | |
| 59 | protected $connection = null; | |
| 60 | ||
| 61 | /** | |
| 62 | * Index from elastic search | |
| 63 | * | |
| 64 | * @var \Elastica\Index|null $index | |
| 65 | */ | |
| 66 | protected $index = null; | |
| 67 | ||
| 68 | /** | |
| 69 | * Due to backward compatibility, the first parameter has two possible meanings | |
| 70 | * | |
| 71 | * @param String $importDirOrLocationFile | |
| 72 | * @param String $servicesFile | |
| 73 | * (optional) | |
| 74 | */ | |
| 75 | public function __construct(mixed $importOrLocationFile, $servicesFile = null) | |
| 76 | { | |
| 77 | if (is_dir($importOrLocationFile)) { | |
| 78 | $this->dldb = new FileAccess(); | |
| 79 | $this->dldb->loadFromPath($importOrLocationFile); | |
| 80 | } elseif (is_file($importOrLocationFile)) { | |
| 81 | $this->dldb = new FileAccess($importOrLocationFile, $servicesFile); | |
| 82 | } else { | |
| 83 | throw new \Exception("Invalid import parameters for ElasticSearch indexer"); | |
| 84 | } | |
| 85 | } | |
| 86 | ||
| 87 | /** | |
| 88 | * | |
| 89 | * @return self | |
| 90 | */ | |
| 91 | public function run() | |
| 92 | { | |
| 93 | $this->readTopics(); | |
| 94 | $this->readServices(); | |
| 95 | $this->readLocations(); | |
| 96 | $this->readAuthorities(); | |
| 97 | return $this; | |
| 98 | } | |
| 99 | ||
| 100 | /** | |
| 101 | * | |
| 102 | * @return array | |
| 103 | */ | |
| 104 | protected function readTopics() | |
| 105 | { | |
| 106 | $esTypeTopic = $this->getIndex()->getType('topic'); | |
| 107 | $esTypeLinks = $this->getIndex()->getType('links'); | |
| 108 | $docs = array(); | |
| 109 | $links = array(); | |
| 110 | foreach ($this->dldb->fromTopic()->fetchList() as $topic) { | |
| 111 | $docs[] = new \Elastica\Document('de' . $topic['id'], $topic); | |
| 112 | if ($topic->isLinked()) { | |
| 113 | $link = array( | |
| 114 | "rank" => 0, | |
| 115 | "link" => "/" . $topic["path"] . "/", | |
| 116 | "name" => $topic['name'], | |
| 117 | "hightlight" => 0, | |
| 118 | "meta" => array( | |
| 119 | "keywords" => $topic['meta']['keywords'], | |
| 120 | "titles" => $topic['meta']['titles'] | |
| 121 | ) | |
| 122 | ); | |
| 123 | $links[] = new \Elastica\Document($link['link'], $link); | |
| 124 | foreach ($topic['links'] as $link) { | |
| 125 | $links[] = new \Elastica\Document($link['link'], $link); | |
| 126 | } | |
| 127 | } | |
| 128 | } | |
| 129 | $esTypeTopic->addDocuments($docs); | |
| 130 | $esTypeLinks->addDocuments($links); | |
| 131 | return $docs; | |
| 132 | } | |
| 133 | ||
| 134 | /** | |
| 135 | * | |
| 136 | * @return array | |
| 137 | */ | |
| 138 | protected function readServices() | |
| 139 | { | |
| 140 | $esType = $this->getIndex()->getType('service'); | |
| 141 | $docs = array(); | |
| 142 | foreach ($this->localeList as $locale) { | |
| 143 | foreach ($this->dldb->fromService($locale)->fetchList() as $service) { | |
| 144 | $serviceId = $locale . $service['id']; | |
| 145 | $docs[] = new \Elastica\Document($serviceId, $service); | |
| 146 | } | |
| 147 | } | |
| 148 | $esType->addDocuments($docs); | |
| 149 | return $docs; | |
| 150 | } | |
| 151 | ||
| 152 | /** | |
| 153 | * | |
| 154 | * @return array | |
| 155 | */ | |
| 156 | protected function readLocations() | |
| 157 | { | |
| 158 | $esType = $this->getIndex()->getType('location'); | |
| 159 | $docs = array(); | |
| 160 | foreach ($this->localeList as $locale) { | |
| 161 | foreach ($this->dldb->fromLocation($locale)->fetchList() as $location) { | |
| 162 | $locationId = $locale . $location['id']; | |
| 163 | $docs[] = new \Elastica\Document($locationId, $location); | |
| 164 | } | |
| 165 | } | |
| 166 | $esType->addDocuments($docs); | |
| 167 | return $docs; | |
| 168 | } | |
| 169 | ||
| 170 | /** | |
| 171 | * | |
| 172 | * @return array | |
| 173 | */ | |
| 174 | protected function readAuthorities() | |
| 175 | { | |
| 176 | $esType = $this->getIndex()->getType('authority'); | |
| 177 | $docs = array(); | |
| 178 | foreach ($this->localeList as $locale) { | |
| 179 | foreach ($this->dldb->fromAuthority($locale)->fetchSource() as $authority) { | |
| 180 | $authorityId = $locale . $authority['id']; | |
| 181 | $docs[] = new \Elastica\Document($authorityId, $authority); | |
| 182 | } | |
| 183 | } | |
| 184 | $esType->addDocuments($docs); | |
| 185 | return $docs; | |
| 186 | } | |
| 187 | ||
| 188 | /** | |
| 189 | * | |
| 190 | * @return \Elastica\Client | |
| 191 | */ | |
| 192 | protected function getConnection() | |
| 193 | { | |
| 194 | if (null === $this->connection) { | |
| 195 | $this->connection = new \Elastica\Client(array( | |
| 196 | 'host' => $this->host, | |
| 197 | 'port' => $this->port, | |
| 198 | 'transport' => $this->transport | |
| 199 | )); | |
| 200 | } | |
| 201 | return $this->connection; | |
| 202 | } | |
| 203 | ||
| 204 | /** | |
| 205 | * | |
| 206 | * @return \Elastica\Index | |
| 207 | */ | |
| 208 | protected function getIndex() | |
| 209 | { | |
| 210 | if (null === $this->index) { | |
| 211 | $connection = $this->getConnection(); | |
| 212 | $this->index = $connection->getIndex(self::ES_INDEX_PREFIX . date(self::ES_INDEX_DATE)); | |
| 213 | if (! $this->index->exists()) { | |
| 214 | $indexSettings = file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . 'ElasticSearch_Index.json'); | |
| 215 | if ($indexSettings === false) { | |
| 216 | $this->index = null; | |
| 217 | throw new \RuntimeException('Cannot read ElasticSearch_Index.json'); | |
| 218 | } | |
| 219 | $indexSettings = json_decode($indexSettings, true); | |
| 220 | $this->index->create($indexSettings); | |
| 221 | } | |
| 222 | } | |
| 223 | return $this->index; | |
| 224 | } | |
| 225 | ||
| 226 | /** | |
| 227 | * | |
| 228 | * @return self | |
| 229 | */ | |
| 230 | public function setHost(mixed $host) | |
| 231 | { | |
| 232 | $this->host = $host; | |
| 233 | return $this; | |
| 234 | } | |
| 235 | ||
| 236 | /** | |
| 237 | * | |
| 238 | * @return self | |
| 239 | */ | |
| 240 | public function setPort(mixed $port) | |
| 241 | { | |
| 242 | $this->port = $port; | |
| 243 | return $this; | |
| 244 | } | |
| 245 | ||
| 246 | /** | |
| 247 | * | |
| 248 | * @return self | |
| 249 | */ | |
| 250 | public function setTransport(mixed $transport) | |
| 251 | { | |
| 252 | $this->transport = $transport; | |
| 253 | return $this; | |
| 254 | } | |
| 255 | ||
| 256 | /** | |
| 257 | * refresh index and add alias | |
| 258 | * | |
| 259 | * @return self | |
| 260 | */ | |
| 261 | public function setAlias(mixed $alias) | |
| 262 | { | |
| 263 | $this->getIndex()->refresh(); | |
| 264 | $this->getIndex()->addAlias($alias, true); | |
| 265 | return $this; | |
| 266 | } | |
| 267 | ||
| 268 | /** | |
| 269 | * Drop all old indice with the prefix ES_INDEX_PREFIX and no alias | |
| 270 | * | |
| 271 | * @return self | |
| 272 | */ | |
| 273 | public function dropOldIndex() | |
| 274 | { | |
| 275 | $client = $this->getConnection(); | |
| 276 | $status = $client->getStatus(); | |
| 277 | $indexList = $status->getIndexNames(); | |
| 278 | $currentIndex = $this->getIndex()->getName(); | |
| 279 | foreach ($indexList as $index) { | |
| 280 | if ($currentIndex != $index && 0 === strpos($index, self::ES_INDEX_PREFIX)) { | |
| 281 | $candidateIndex = $client->getIndex($index); | |
| 282 | if (! $candidateIndex->getStatus()->getAliases()) { | |
| 283 | $candidateIndex->delete(); | |
| 284 | } | |
| 285 | } | |
| 286 | } | |
| 287 | return $this; | |
| 288 | } | |
| 289 | } |