|
36 | 36 | Credits and inspiration sources |
37 | 37 | ------------------------------- |
38 | 38 |
|
| 39 | +Search concept |
| 40 | +-------------- |
| 41 | +*for now it works only with STATIC VALUES property storage* |
| 42 | + |
| 43 | +*Note, that search will work only with models with `DevGroup\DataStructure\traits\PropertiesTrait` trait |
| 44 | +and `DevGroup\DataStructure\behaviors\HasProperties` behavior connected. See [how to connect (Russian for now)](/docs/ru/how-to-use.md)* |
| 45 | + |
| 46 | +Extension provides flexible system of search. Each property have configuration point that switches ability to use this property in search. |
| 47 | + |
| 48 | +Basic search will be done in two ways: |
| 49 | + |
| 50 | +- common search against regular databases e.g.: `mysql`, `mariadb` etc; |
| 51 | +- elasticsearch indices search. |
| 52 | + |
| 53 | +Main feature is that if you want to use elasticseatch, and defined it in the app config, |
| 54 | +but not still configure it your search will just work fine with auto fallback to simple mysql searching. And when your |
| 55 | +elasticsearch will be properly started search will be automatically switched for elasticseatch. |
| 56 | + |
| 57 | +Preferred search mechanism you can define in the application configuration files, like this: |
| 58 | +``` |
| 59 | + 'modules' => [ |
| 60 | + ... |
| 61 | + 'properties' => [ |
| 62 | + 'class' => 'DevGroup\DataStructure\Properties\Module', |
| 63 | + 'searchClass' => \DevGroup\DataStructure\search\elastic\Search::class, |
| 64 | + 'searchConfig' => [ |
| 65 | + 'hosts' => ['host1:9200', 'https://host2:9200'], |
| 66 | + 'watcherClass' => MyWatch::class, |
| 67 | + ] |
| 68 | + |
| 69 | + ], |
| 70 | + ... |
| 71 | + ], |
| 72 | +``` |
| 73 | + |
| 74 | +- `searchClass` - class to be used for search. If omit - there will be no search configured, |
| 75 | +- `searchConfig` - array additional parameters to be applied for search object, except common search. |
| 76 | + For elastic search following special keys may be set: |
| 77 | + - `hosts` see [hosts config](https://www.elastic.co/guide/en/elasticsearch/client/php-api/current/_configuration.html), |
| 78 | + - `watcherClass` - you can use your own watcher for elsticsearch if needed. |
| 79 | + |
| 80 | +If you want to start using elasticsearch, first of all you have to [install and configure it](https://www.elastic.co/guide/en/elasticsearch/reference/current/setup.html). |
| 81 | + |
| 82 | +Then, if you already have entries in your database you may want to generate and load start indices. For this run in console: |
| 83 | +``` |
| 84 | +./yii properties/elastic/fill-index |
| 85 | +``` |
| 86 | +This command will create indices for all properties that you allowed to search. |
| 87 | + |
| 88 | +# How to search |
| 89 | +*For now only available to perform filtering against properties static values* |
| 90 | +## At any place you want |
| 91 | +``` |
| 92 | +<?= \DevGroup\DataStructure\search\elastic\widgets\FilterFormWidget::widget([ |
| 93 | + 'modelClass' => \app\models\Page::class, |
| 94 | + 'filterRoute' => ['/url/to/filter'], |
| 95 | + 'options' => [ |
| 96 | + 'storage' => [ |
| 97 | + EAV::class, |
| 98 | + StaticValues::class, |
| 99 | + ] |
| 100 | + ] |
| 101 | +]) ?> |
| 102 | +``` |
| 103 | +This will render basic filter form with all properties and values contained in the elasticsearch index |
| 104 | +- `'modelClass'` - required param, any model class name you have in your app with assigned properties and their static values, |
| 105 | +- `'filterRoute'` - required param, `action` attribute for rendered filter form, |
| 106 | +- `'options'` - optional, additional array of config. Special key `storage` will be used for definition against what property storage |
| 107 | +search will be proceed. If you omit it search will be work only against `StaticValues` storage by default |
| 108 | + |
| 109 | +## In your controller |
| 110 | +``` |
| 111 | +public function actionFilter() |
| 112 | +{ |
| 113 | + /** @var AbstractSearch $component */ |
| 114 | + $search = \Yii::$app->getModule('properties')->getSearch(); |
| 115 | + $config = ['storage' => [ |
| 116 | + EAV::class, |
| 117 | + StaticValues::class, |
| 118 | + ] |
| 119 | + ]; |
| 120 | + $modelIds = $search->findInProperties(Page::class, $config); |
| 121 | + $dataProvider = new ActiveDataProvider([ |
| 122 | + //provider config |
| 123 | + ]); |
| 124 | + //other stuff here |
| 125 | +} |
| 126 | +``` |
| 127 | +- `Page` - any model class name you have in your app with assigned properties and their static values |
| 128 | +- `$modelIds` will contain all found model ids, according to selected property values in filter. Using them you can show anything you want, |
| 129 | +- `'$config'` - optional, additional array of config. Special key `storage` will be used for definition against what property storage |
| 130 | +search will be proceed. If you omit it search will be work only against `StaticValues` storage by default |
| 131 | + |
| 132 | +## Filtering logic |
| 133 | + |
| 134 | +Filters uses both intersection and union operations while search. |
| 135 | + |
| 136 | +Lets see, for example you have filter request like this: |
| 137 | +``` |
| 138 | +[ |
| 139 | + 1 => [2,3], |
| 140 | + 13 => [18,9,34] |
| 141 | +] |
| 142 | +``` |
| 143 | +First of all this means that we want to find products that has property values assigned with id 2,3 from property with id 1, |
| 144 | +and 18, 9, 34 from property with id 13. |
| 145 | + |
| 146 | +*What will filter do?* |
| 147 | +- For now it will find all products with assigned values with ids IN(2,3); |
| 148 | +- then it will find all products with assigned values with ids IN(12,9,34); |
| 149 | +- and finally it will return to you result of intersection from both previous results. |
| 150 | + |
| 151 | +## How to extend and implement |
| 152 | +For all `Search` and `Watch` mechanisms you can use your custom implementation. |
| 153 | + |
| 154 | +Actually you can create and use your own database connection, e.g.: `MongoDB`, `ArangoDB`. |
| 155 | + |
| 156 | +Or you can just use your custom `Watch` class for elasticsearch index actualization. |
| 157 | + |
| 158 | +Both `Search` and `Watch` classes are implements according interfaces and extends abstract classes |
| 159 | +- `DevGroup\DataStructure\search\interfaces\Search` and `DevGroup\DataStructure\search\base\AbstractSearch` for `Search` |
| 160 | +- `DevGroup\DataStructure\search\interfaces\Watch` and `DevGroup\DataStructure\search\base\AbstractWatch` for `Watch` |
| 161 | + |
| 162 | +Just extend your class from needed abstract class and define it in application config, like described upper. |
| 163 | + |
| 164 | +If you are realizing custom index, you probably need to create own controller for first time index initialization, like |
| 165 | +`DevGroup\DataStructure\commands\ElasticIndexController` |
| 166 | + |
| 167 | +Define your own `Watch` class in your own `Search` class if necessary. |
| 168 | + |
| 169 | +Clearly created and defined `Watch` class will be automatically subscribed to according system events. |
| 170 | + |
| 171 | + |
| 172 | + |
39 | 173 |
|
0 commit comments