dimvic / yii-elastic
Yii 1.1 elasticsearch tools
Installs: 145
Dependents: 0
Suggesters: 0
Security: 0
Stars: 7
Watchers: 2
Forks: 3
Open Issues: 1
Type:yii-extension
Requires
- php: ^5.4.0|^7.0
- dimvic/composer-installers: dev-master
- ruflin/elastica: 3.2.*
Requires (Dev)
- roave/security-advisories: dev-master
Suggests
- yiisoft/yii: ^1.1.17
This package is not auto-updated.
Last update: 2022-08-06 07:45:19 UTC
README
Set of tools for working with elasticsearch in Yii 1.1 projects. Includes a CActiveDataProvider
compatible data provider, a CActiveRecordBehavior
and an elasticsearch query helper.
Apart for enabling an application for speedy searches using elasticsearch, the tools also enable for searches inside relations with near zero configuration.
Features
- No elasticsearch background required
- ElasticActiveRecordBehavior
- Automatically indexed (documents are added and deleted from elasticsearch when a record is inserted/updated/deleted)
- Automatic indexing of relations and even their relations at any depth (minimal configuration required)
- ElasticDataProvider
- Compatible with CGridView, CListView, etc. Use
$model->elasticSearch()
instead of$model->search()
- Fully compatible with CActiveDataProvider, all pagination and sorting is supported
- Search supports all operands it is expected to (all operands supported by
CDbCriteria->compare())
, >, <, >=, <>, etc) - Returns CActiveRecord[], not elasticsearch documents, for maximum compatibility
- Compatible with CGridView, CListView, etc. Use
- ElasticQueryHelper
- Build elasticsearch queries (implements CDbCriteria->compare(), works for relations)
- Search inside relations' fields (
category.products.price>10
just works)
Caveats
- This will only work for
CActiveRecord
implementations with one single primary key (any type), composite primary keys are not supported. ElasticDataProvider
uses elasticsearch to search but returnsCActiveRecord[]
, NOT an array of elasticsearch documents. It fetches the primary keys for the matched records and in turn queries by primary key in order to returnCActiveRecord[]
for maximum compatibility with Yii 1.1 widgets/extensions/components/plugins.- Searching inside relation fields currently only works for a full match ("imba" will not match "imbalanced" as you might expect)
Installation
$ composer require dimvic/yii-elastic:dev-master
$ composer update
Then Add to your configuration:
return [ ... 'components' => [ 'elastica' => [ 'class' => 'extensions.yii-elastic.Elastica', 'host' => '127.0.0.1', 'port' => '9200', 'debug' => YII_DEBUG, ], ... ], ... ];
Getting started
Attach ElasticActiveRecordBehavior
to a CActiveRecord
:
class Post extends CActiveRecord { ... public function Behaviors() { return array_replace(parent::behaviors(), [ [ 'class'=>'ext.yii-elastic.ElasticActiveRecordBehavior', 'elastic_index'=>null, //defaults to parsing db name from $this->getDbConnection() 'elastic_type'=>null, //defaults to $model->tableName() 'elastic_raw_cols'=>null,//the columns that will be used for aggregations, defaults to ['caption', 'slug', 'label', 'name'] 'elastic_relations'=>[ //the relations you want indexed, can be nested to any depth 'author', 'author.group', ], ], ... ]); } ... ]
Index the model's data in elastic
This will create the index and type in elasticsearch, and it will delete them first if they already exist! It will also index all data, so have a look at the method's parameters if you intend to run it on big data sets.
Post::model()->elasticRebuild();
Ready
In your controller:
public function actionGrid() { $model = new Post('search'); $this->render('grid', [ 'model' => $model, ]); }
In your view:
$this->widget('zii.widgets.grid.CGridView', [ 'dataProvider'=>$model->elasticSearch(), 'filter'=>$model, 'columns' => [ ['name'=>'id'], ['name'=>'title'], ['name'=>'author.name', 'filter'=>$model->nestedFilterInput('author.name')], ['name'=>'author.group.name', 'filter'=>$model->nestedFilterInput('author.group.name')], ], 'ajaxUpdate'=>false, ]);
And you can already search by the post author's group name.
Usage
Although the default functionality should be enough for most cases, you can handle more complex scenarios with ease.
You will probably want to have a look at:
ElasticActiveRecordBehavior->elasticSearch()
if you want to run custom queriesElasticActiveRecordBehavior->createElasticType()
andElasticActiveRecordBehavior->elasticProperties()
if you want to index your data in a specific way (you will probably want to overrideElasticActiveRecordBehavior->createElasticDocument()
which prepares the documents as well)ElasticQueryHelper
to get an idea of how queries are build Playing with the parameters of the methods should be enough for most cases, overriding is always an option.
ElasticActiveDataProvider->getResultSet()
will give you access to the \Elastica\ResultSet
for every query, in case you need more insight on the search you perform.
Thanks
Todo
- Add
$model->relations()
to index by default ElasticaQueryHelper::compare()
dates support- Create a schema cache for the relational fields, as they will always be searched for exact matches ATM
- Support aggregations for model and relation fields
- Documentation