How to use elastic search in yii2
- Digital Engineering
How to use elastic search in yii2
Elastic Search can be implemented in yii2 easily. You need to setup server and elastic search before to use.
After elastic search setup, you need to install the yii2 extension
https://github.com/yiisoft/yii2-elasticsearch/blob/master/docs/guide/README.md
Configure in common/main.php file
1 2 3 4 5 6 7 8 9 10 |
'components' => [ 'elasticsearch' => [ 'class' => 'yii\elasticsearch\Connection', 'nodes' => [ ['http_address' => '127.0.0.1:9200'], // configure more hosts if you have a cluster ], ], ] |
Creating index and mapping
Since it is not always possible to update ElasticSearch mappings incrementally, it is a good idea to create several static methods in your model that deal with index creation and updates. Here is one example of how this can be done.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
Class Book extends yii\elasticsearch\ActiveRecord { public static function index(){ return "Catalog" } public static function type(){ return "Book"; } /** * @return array This model's mapping */ public static function mapping() { return [ static::type() => [ 'properties' => [ 'id' => ['type' => 'long'], 'name' => ['type' => 'string'], 'author_name' => ['type' => 'string', "index"=>"not_analyzed"], 'publisher_name' => ['type' => 'string', "index"=>"not_analyzed"], 'created_at' => ['type' => 'long'], 'updated_at' => ['type' => 'long'], 'status' => ['type' => 'long'], 'suppliers' => [ 'type' => 'nested', 'properties' => [ 'id' => ['type' => 'long'], 'name' => ['type' => 'string', 'index' => 'not_analyzed'], ] ] ] ], ]; } /** * Set (update) mappings for this model */ public static function updateMapping() { $db = static::getDb(); $command = $db->createCommand(); $command->setMapping(static::index(), static::type(), static::mapping()); } /** * Create this model's index */ public static function createIndex() { $db = static::getDb(); $command = $db->createCommand(); $command->createIndex(static::index(), [ 'settings' => [ 'index' => ['refresh_interval' => '1s'] ], 'mappings' => static::mapping(), //'warmers' => [ /* ... */ ], //'aliases' => [ /* ... */ ], //'creation_date' => '...' ]); } /** * Delete this model's index */ public static function deleteIndex() { $db = static::getDb(); $command = $db->createCommand(); $command->deleteIndex(static::index(), static::type()); } public static function updateRecord($book_id, $columns){ try{ $record = self::get($book_id); foreach($columns as $key => $value){ $record->$key = $value; } return $record->update(); } catch(\Exception $e){ //handle error here return false; } } public static function deleteRecord($book_id) { try{ $record = self::get($book_id); $record->delete(); return 1; } catch(\Exception $e){ //handle error here return false; } } public static function addRecord(Book $book){ $isExist = false; try{ $record = self::get($book->id); if(!$record){ $record = new self(); $record->setPrimaryKey($book->id); } else{ $isExist = true; } } catch(\Exception $e){ $record = new self(); $record->setPrimaryKey($book->id); } $suppliers = [ ['id' => '1', 'name' => 'ABC'], ['id' => '2', 'name' => 'XYZ'], ]; $record->id = $book->id; $record->name = $book->name; $record->author_name = $image->author_name; $record->status = 1; $record->suppliers = $suppliers; try{ if(!$isExist){ $result = $record->insert(); } else{ $result = $record->update(); } } catch(\Exception $e){ $result = false; //handle error here } return $result; } } |
By using above class, you can create index and mapping. Also you can add records in Book index.
Querying the data by yii\elasticsearch\Query
1 2 3 4 5 6 7 8 9 |
use yii\elasticsearch\Query; $query = new Query(); $query->source('*'); $query->from(Book::index(), Book::type())->limit(10); //build and execute the query $command = $query->createCommand(); $rows = $command->search(); // this way you get the raw output of elasticsearch. |
Adding aggregation in query
1 2 |
$query->addAggregation("status", "terms", array("field"=>"status" , "order" => ['_term' => "asc"])); $query->addAggregation("author_name", "terms", array("field"=>"author_name",'size' => 25)); |
Adding filters in query
1 2 3 4 5 6 7 8 9 10 11 12 13 |
$filters = []; $filters['bool']['must'][]['term']['status'] = 1; //nested filters $filter = []; $filter['nested']['path'] = 'suppliers'; $filter['nested']['query']['bool']['must'][]['match']['suppliers.name'] = 'XYZ'; $filter['nested']['query']['bool']['must'][]['match']['suppliers.id'] = 1; $filters['bool']['must'][] = $filter; if($filters){ $query->query($filters); } |
Adding sorting in results
1 |
$query->orderBy = ['id' => ['order' => 'desc']]; |
Paging and render results
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
try{ $pages = new Pagination(['totalCount' => $query->count() , "defaultPageSize" => $limit]); $offset = ($page-1)*$limit; $query->offset($offset)->limit($limit); $command = $query->createCommand(); $rows = $command->search(); } catch(\Exception $e){ $message = $e->getMessage(); return $this->render("/site/error",['name'=> "Search Results",'message' => "Search service is currently not working, Please try again later."]); } $aggregations = $rows['aggregations']; $provider = new ArrayDataProvider([ 'allModels' => $rows['hits']['hits'], 'pagination' => [ 'pageSize' => $limit, ], ]); |
Related content
Auriga: Leveling Up for Enterprise Growth!
Auriga’s journey began in 2010 crafting products for India’s