elastic-yii ¶
Set of tools for working with elasticsearch using Elastica for those stuck with projects in Yii 1.1. Includes a CActiveDataProvider compatible data provider, a CActiveRecord behavior and an elasticsearch query helper.
You might actually enjoy using it, not only because it allows for speedy searches, but also because it enables you to search inside relations with near zero configuration.
Requirements ¶
- PHP 5.4+
- Yii 1.1.16 (Should work with at least 1.1.11+, but not tested)
Features ¶
- No elasticsearch background required, a very simple installation is all that is needed (you don't even need to manually create an index or type in elasticsearch)
- 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. Just use
`
$model->elasticSearch()instead of
$model->search()`
- Fully compatible with CActiveDataProvider, all pagination and sorting is supported
- Search supports all the operands that you expect it to (all that are supported by
`
CDbCriteria->compare())`
, >, <, >=, <>, etc) - Returns CActiveRecord[] just like CActiveDataProvider for maximum compatibility (see caveats)
- Compatible with CGridView, CListView, etc. Just use
- ElasticQueryHelper
- Build elasticsearch queries (implements CDbCriteria->compare(), works for relations)
- Effortlessly search using relations' fields (
`
category.products.price>10`
just works)
Notes ¶
This is something I put together because of a a project I am working on and by no means do I consider it a complete abstraction for elasticsearch, not even close. Though, it should cover the needs for most projects and you can work with elasticsearch in Yii comfortably.
No unit tests have been implemented, they might be added if I need to add more features.
No composer support, Yii 1.1 does directly support it.
Feel free to help out to add functionality if you feel like it, I'd be more than grateful for any feedback/help.
Caveats ¶
- This will only work for
`
CActiveRecord`
implementations with one primary key (any type), composite primary keys are not (and will not be) supported. - Searching on relation fields currently only works for a full match ("imba" will not match "imbalanced" as you might expect)
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
- Support Elastica installation in folder other than
`
elastic-yii/Elastica`
- Documentation
Installation ¶
- Clone this repository into
`
extensions/`
- Run
`
git submodule update --init --recursivein
extensions/elastic-yii`
- Add to your configuration:
return [ 'preload' => [ 'elasticaLoader', ... ], ... 'components' => [ 'elastica' => [ 'class' => 'extensions.elastic-yii.Elastica.lib.Elastica.Elastica', 'host' => '127.0.0.1', 'port' => '9200', 'debug' => YII_DEBUG, ], 'elasticaLoader' => [ 'class' => 'ext.elastic-yii.ElasticaLoader', ], ... ], ... ];
Getting started ¶
Attach the behacior to a model ¶
class Post extends CActiveRecord
{
...
public function Behaviors()
{
return array_replace(parent::behaviors(), [
[
'class'=>'ext.elastic-yii.ElasticActiveRecordBehavior',
'elastic_index'=>null, //defaults to parsing db name from $this->getDbConnection()
'elastic_type'=>null, //defaults to $model->tableName()
'elastic_raw_cols'=>null,//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 ¶
Beware! 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 parameters the method accepts if you intend to run it on big data sets.
`
php
Post::model()->elasticRebuild();
`
Ready ¶
In your controller:
`
php
public function actionGrid() {
$model = new Post('search');
$this->render('grid', [
'model' => $model,
]);
}
`
In your view:
`
php
$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.
Or you might prefer to have it like this:
`
php
$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.id',
'value'=>'$data->author->group->name'
'filter'=>CHtml::listData(Group::model()->findall(), 'id', 'name'),
],
],
'ajaxUpdate'=>false,
]);
`
Usage ¶
Although the default functionality should be enough for more cases, you can handle more complex scenarios with ease.
You will probably want to have a look at:
Playing with the parameters of the methods should be enough for most cases, overloading is always an option.
Also, `
ElasticActiveDataProvider->getResultSet()will give you access to the
\Elastica\ResultSet`
for every query, in case you need more insights on the search you perform.
@todo add usage tips
Methods Overview ¶
@todo add methods overview
Thanks ¶
Many thanks to
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.