This class implements the ActiveRecord pattern for the fulltext search and data storage elasticsearch. For defining a record a subclass should at least implement the ActiveRecord::attributes method to define attributes. The primary key (the _id field in elasticsearch terms) is represented by getId() and setId(). The primary key is not part of the attributes. The following is an example model called Customer: php class Customer extends \yii\elasticsearch\ActiveRecord { public function attributes() { return ['id', 'name', 'address', 'registration_date']; } } You may override ActiveRecord::index and ActiveRecord::type to define the index and type this record represents.
Since: 2.0
Author: Carsten Brandt (mail@cebe.cc)
Inheritance: extends yii\db\BaseActiveRecord
 public function down()
 {
     $index = \gromver\platform\common\models\elasticsearch\ActiveDocument::index();
     \yii\elasticsearch\ActiveRecord::getDb()->createCommand()->deleteIndex($index);
     //->deleteAllIndexes();//
     echo "Index {$index} are deleted successfully.";
 }
 /**
  * @param $documentClass \gromver\platform\common\models\elasticsearch\ActiveDocument
  * @return int
  * @throws \yii\elasticsearch\Exception
  */
 public function upload($documentClass)
 {
     $bulk = '';
     /** @var \yii\db\ActiveRecord|string $modelClass */
     $modelClass = $documentClass::model();
     /** @var \gromver\platform\common\models\elasticsearch\ActiveDocument $document */
     $document = new $documentClass();
     $uploaded = 0;
     foreach ($modelClass::find()->each() as $model) {
         /** @var \yii\db\ActiveRecord $model */
         $action = Json::encode(["index" => ["_id" => $model->getPrimaryKey(), "_type" => $documentClass::type(), "_index" => $documentClass::index()]]);
         $document->loadModel($model);
         $data = Json::encode($document->toArray());
         $bulk .= $action . "\n" . $data . "\n";
         $uploaded++;
     }
     $url = [$documentClass::index(), $documentClass::type(), '_bulk'];
     $response = ActiveRecord::getDb()->post($url, [], $bulk);
     $n = 0;
     $errors = [];
     foreach ($response['items'] as $item) {
         if (isset($item['index']['status']) && ($item['index']['status'] == 201 || $item['index']['status'] == 200)) {
             $n++;
         } else {
             $errors[] = $item['index'];
         }
     }
     if (!empty($errors) || isset($response['errors']) && $response['errors']) {
         throw new Exception(__METHOD__ . ' failed inserting ' . $modelClass . ' model records.', $errors);
     }
     return $n;
 }
Example #3
0
 /**
  * @inheritdoc
  */
 public function beforeSave($insert)
 {
     if (!parent::beforeSave($insert)) {
         return false;
     }
     $this->refreshFromEmbedded();
     return true;
 }
 public function down()
 {
     if (!($index = Index::index())) {
         throw new Exception(Index::className() . '::index must be set.');
     }
     ActiveRecord::getDb()->createCommand()->deleteIndex($index);
     //->deleteAllIndexes();//
     echo "Index {$index} are deleted successfully.";
 }
 /**
  * @param $class \yii\db\ActiveRecord|string
  * @return int
  * @throws \yii\elasticsearch\Exception
  */
 public function upload($class)
 {
     $bulk = '';
     $index = Index::index();
     $type = Index::type();
     $timestamp = time();
     /** @var \yii\base\Behavior[] */
     $behaviors = (new $class())->behaviors;
     $query = $class::find();
     array_walk($behaviors, function ($behavior) use($query) {
         if ($behavior instanceof TaggableBehavior) {
             $query->with('tags');
         }
     });
     foreach ($query->each() as $model) {
         /** @var \yii\db\ActiveRecord|\gromver\platform\core\interfaces\model\SearchableInterface|\gromver\platform\core\interfaces\model\ViewableInterface $model */
         $action = Json::encode(["index" => ["_id" => $model->getPrimaryKey(), "_type" => $type, "_index" => $index]]);
         $indexModel = Index::findOne(['model_id' => $model->getPrimaryKey(), 'model_class' => $model->className()]) or $indexModel = new Index();
         $indexModel->model_id = $model->getPrimaryKey();
         $indexModel->model_class = $model->className();
         $indexModel->title = $model->getSearchTitle();
         $indexModel->content = $model->getSearchContent();
         $indexModel->tags = $model->getSearchTags();
         $indexModel->url_backend = $model->getBackendViewLink();
         $indexModel->url_frontend = $model->getFrontendViewLink();
         $indexModel->updated_at = $timestamp;
         ModuleEvent::trigger(Module::EVENT_BEFORE_CREATE_INDEX . $model->className(), new ElasticIndexEvent(['model' => $model, 'index' => $indexModel, 'sender' => $this->module]));
         if ($indexModel->validate()) {
             $bulk .= $action . "\n" . Json::encode($indexModel->toArray()) . "\n";
         }
     }
     $url = [$index, $type, '_bulk'];
     $response = ActiveRecord::getDb()->post($url, [], $bulk);
     $n = 0;
     $errors = [];
     foreach ($response['items'] as $item) {
         if (isset($item['index']['status']) && ($item['index']['status'] == 201 || $item['index']['status'] == 200)) {
             $n++;
         } else {
             $errors[] = $item['index'];
         }
     }
     if (!empty($errors) || isset($response['errors']) && $response['errors']) {
         throw new Exception(__METHOD__ . ' failed inserting ' . $class . ' model records.', $errors);
     }
     return $n;
 }
Example #6
0
 /**
  * @inheritdoc
  *
  * @param ActiveRecord $record the record to be populated. In most cases this will be an instance
  * created by [[instantiate()]] beforehand.
  * @param array $row attribute values (name => value)
  */
 public static function populateRecord($record, $row)
 {
     $attributes = [];
     if (isset($row['_source'])) {
         $attributes = $row['_source'];
     }
     if (isset($row['fields'])) {
         // reset fields in case it is scalar value
         $arrayAttributes = $record->arrayAttributes();
         foreach ($row['fields'] as $key => $value) {
             if (!isset($arrayAttributes[$key]) && count($value) == 1) {
                 $row['fields'][$key] = reset($value);
             }
         }
         $attributes = array_merge($attributes, $row['fields']);
     }
     parent::populateRecord($record, $attributes);
     $pk = static::primaryKey()[0];
     //TODO should always set ID in case of fields are not returned
     if ($pk === '_id') {
         $record->_id = $row['_id'];
     }
     $record->_highlight = isset($row['highlight']) ? $row['highlight'] : null;
     $record->_score = isset($row['_score']) ? $row['_score'] : null;
     $record->_version = isset($row['_version']) ? $row['_version'] : null;
     // TODO version should always be available...
 }
 public function behaviors()
 {
     return array_merge(parent::behaviors(), [TimestampBehavior::className()]);
 }