the browser-facing portion of osu!
at master 123 lines 3.4 kB view raw
1<?php 2 3// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the GNU Affero General Public License v3.0. 4// See the LICENCE file in the repository root for full licence text. 5 6namespace App\Models\Traits\Es; 7 8use App\Libraries\Elasticsearch\Es; 9use Log; 10 11trait BaseDbIndexable 12{ 13 use BaseIndexable; 14 15 abstract public static function esIndexingQuery(); 16 17 public static function esIndexIntoNew($batchSize = 1000, $name = null, callable $progress = null) 18 { 19 $newIndex = $name ?? static::esTimestampedIndexName(); 20 Log::info("Creating new index {$newIndex}"); 21 static::esCreateIndex($newIndex); 22 23 $options = [ 24 'index' => $newIndex, 25 ]; 26 27 static::esReindexAll($batchSize, 0, $options, $progress); 28 29 return $newIndex; 30 } 31 32 public static function esIndexName() 33 { 34 return $GLOBALS['cfg']['osu']['elasticsearch']['prefix'].(new static())->getTable(); 35 } 36 37 public static function esSchemaFile() 38 { 39 return config_path('schemas/'.(new static())->getTable().'.json'); 40 } 41 42 public static function esReindexAll($batchSize = 1000, $fromId = 0, array $options = [], callable $progress = null) 43 { 44 $dummy = new static(); 45 $startTime = time(); 46 47 $baseQuery = static::esIndexingQuery()->where($dummy->getKeyName(), '>', $fromId); 48 $count = 0; 49 50 $baseQuery->chunkById($batchSize, function ($models) use ($options, &$count, $progress) { 51 $actions = Es::generateBulkActions($models); 52 53 if ($actions !== []) { 54 $result = Es::getClient()->bulk([ 55 'index' => $options['index'] ?? static::esIndexName(), 56 'body' => $actions, 57 'client' => ['timeout' => 0], 58 ]); 59 60 $count += count($result['items']); 61 } 62 63 Log::info(static::class." next: {$models->last()->getKey()}"); 64 if ($progress) { 65 $progress($count); 66 } 67 }); 68 69 $duration = time() - $startTime; 70 Log::info(static::class." Indexed {$count} records in {$duration} s."); 71 } 72 73 /** 74 * The value for routing. 75 * Override to provide a routing value; null by default. 76 * 77 * @return string|null 78 */ 79 public function esRouting() 80 { 81 // null will be omitted when used as routing. 82 } 83 84 public function esDeleteDocument(array $options = []) 85 { 86 $document = array_merge([ 87 'index' => static::esIndexName(), 88 'routing' => $this->esRouting(), 89 'id' => $this->getEsId(), 90 'client' => ['ignore' => 404], 91 ], $options); 92 93 return Es::getClient()->delete($document); 94 } 95 96 public function esIndexDocument(array $options = []) 97 { 98 if (!$this->esShouldIndex()) { 99 return $this->esDeleteDocument($options); 100 } 101 102 $document = array_merge([ 103 'index' => static::esIndexName(), 104 'routing' => $this->esRouting(), 105 'id' => $this->getEsId(), 106 'body' => $this->toEsJson(), 107 ], $options); 108 109 return Es::getClient()->index($document); 110 } 111 112 public function esShouldIndex() 113 { 114 return true; 115 } 116 117 public function getEsId() 118 { 119 return $this->getKey(); 120 } 121 122 abstract public function toEsJson(); 123}