README.md 8.31 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11
Elasticsearch Query and ActiveRecord for Yii 2
==============================================

This extension provides the [elasticsearch](http://www.elasticsearch.org/) integration for the Yii2 framework.
It includes basic querying/search support and also implements the `ActiveRecord` pattern that allows you to store active
records in elasticsearch.

To use this extension, you have to configure the Connection class in your application configuration:

```php
return [
12 13
    //....
    'components' => [
14 15
        'elasticsearch' => [
            'class' => 'yii\elasticsearch\Connection',
Carsten Brandt committed
16
            'nodes' => [
17
                ['http_address' => '127.0.0.1:9200'],
18 19 20
                // configure more hosts if you have a cluster
            ],
        ],
21
    ]
22 23 24
];
```

25 26 27 28
Requirements
------------

elasticsearch version 1.0 or higher is required.
29 30 31 32 33 34 35 36 37

Installation
------------

The preferred way to install this extension is through [composer](http://getcomposer.org/download/).

Either run

```
38
php composer.phar require --prefer-dist yiisoft/yii2-elasticsearch "*"
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
```

or add

```json
"yiisoft/yii2-elasticsearch": "*"
```

to the require section of your composer.json.


Using the Query
---------------

TBD

55 56 57 58
> **NOTE:** elasticsearch limits the number of records returned by any query to 10 records by default.
> If you expect to get more records you should specify limit explicitly in relation definition.


59 60 61 62 63
Using the ActiveRecord
----------------------

For general information on how to use yii's ActiveRecord please refer to the [guide](https://github.com/yiisoft/yii2/blob/master/docs/guide/active-record.md).

64 65
For defining an elasticsearch ActiveRecord class your record class needs to extend from [[yii\elasticsearch\ActiveRecord]] and
implement at least the [[yii\elasticsearch\ActiveRecord::attributes()|attributes()]] method to define the attributes of the record.
66
The handling of primary keys is different in elasticsearch as the primary key (the `_id` field in elasticsearch terms)
Carsten Brandt committed
67 68 69
is not part of the attributes by default. However it is possible to define a [path mapping](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/mapping-id-field.html)
for the `_id` field to be part of the attributes.
See [elasticsearch docs](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/mapping-id-field.html) on how to define it.
70 71 72
The `_id` field of a document/record can be accessed using [[yii\elasticsearch\ActiveRecord::getPrimaryKey()|getPrimaryKey()]] and
[[yii\elasticsearch\ActiveRecord::setPrimaryKey()|setPrimaryKey()]].
When path mapping is defined, the attribute name can be defined using the [[yii\elasticsearch\ActiveRecord::primaryKey()|primaryKey()]] method.
73 74 75 76 77 78

The following is an example model called `Customer`:

```php
class Customer extends \yii\elasticsearch\ActiveRecord
{
Carsten Brandt committed
79 80 81
    /**
     * @return array the list of attributes for this record
     */
82 83
    public function attributes()
    {
Carsten Brandt committed
84
        // path mapping for '_id' is setup to field 'id'
85 86
        return ['id', 'name', 'address', 'registration_date'];
    }
Carsten Brandt committed
87 88

    /**
89
     * @return ActiveQuery defines a relation to the Order record (can be in other database, e.g. redis or sql)
Carsten Brandt committed
90 91 92 93 94 95 96 97 98 99 100
     */
    public function getOrders()
    {
        return $this->hasMany(Order::className(), ['customer_id' => 'id'])->orderBy('id');
    }

    /**
     * Defines a scope that modifies the `$query` to return only active(status = 1) customers
     */
    public static function active($query)
    {
Luciano Baraglia committed
101
        $query->andWhere(['status' => 1]);
Carsten Brandt committed
102
    }
103 104 105
}
```

106 107
You may override [[yii\elasticsearch\ActiveRecord::index()|index()]] and [[yii\elasticsearch\ActiveRecord::type()|type()]]
to define the index and type this record represents.
108 109 110 111 112 113 114

The general usage of elasticsearch ActiveRecord is very similar to the database ActiveRecord as described in the
[guide](https://github.com/yiisoft/yii2/blob/master/docs/guide/active-record.md).
It supports the same interface and features except the following limitations and additions(*!*):

- As elasticsearch does not support SQL, the query API does not support `join()`, `groupBy()`, `having()` and `union()`.
  Sorting, limit, offset and conditional where are all supported.
115 116
- [[yii\elasticsearch\ActiveQuery::from()|from()]] does not select the tables, but the
  [index](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/glossary.html#glossary-index)
117
  and [type](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/glossary.html#glossary-type) to query against.
118 119
- `select()` has been replaced with [[yii\elasticsearch\ActiveQuery::fields()|fields()]] which basically does the same but
  `fields` is more elasticsearch terminology.
120
  It defines the fields to retrieve from a document.
121 122 123 124 125
- [[yii\elasticsearch\ActiveQuery::via()|via]]-relations can not be defined via a table as there are no tables in elasticsearch. You can only define relations via other records.
- As elasticsearch is not only a data storage but also a search engine there is of course support added for searching your records.
  There are
  [[yii\elasticsearch\ActiveQuery::query()|query()]],
  [[yii\elasticsearch\ActiveQuery::filter()|filter()]] and
Carsten Brandt committed
126
  [[yii\elasticsearch\ActiveQuery::addFacet()|addFacet()]] methods that allows to compose an elasticsearch query.
127 128
  See the usage example below on how they work and check out the [Query DSL](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl.html)
  on how to compose `query` and `filter` parts.
Carsten Brandt committed
129 130
- It is also possible to define relations from elasticsearch ActiveRecords to normal ActiveRecord classes and vice versa.

131 132 133 134 135 136
> **NOTE:** elasticsearch limits the number of records returned by any query to 10 records by default.
> If you expect to get more records you should specify limit explicitly in query **and also** relation definition.
> This is also important for relations that use via() so that if via records are limited to 10
> the relations records can also not be more than 10.


Carsten Brandt committed
137 138 139 140
Usage example:

```php
$customer = new Customer();
Carsten Brandt committed
141
$customer->primaryKey = 1; // in this case equivalent to $customer->id = 1;
Carsten Brandt committed
142 143 144 145
$customer->attributes = ['name' => 'test'];
$customer->save();

$customer = Customer::get(1); // get a record by pk
Carsten Brandt committed
146
$customers = Customer::mget([1,2,3]); // get multiple records by pk
Carsten Brandt committed
147
$customer = Customer::find()->where(['name' => 'test'])->one(); // find by query
148 149 150 151 152 153 154
$customers = Customer::find()->active()->all(); // find all by query (using the `active` scope)

// http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-field-query.html
$result = Article::find()->query(["field" => ["title" => "yii"]])->all(); // articles whose title contains "yii"

// http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-flt-query.html
$query = Article::find()->query([
155 156 157
    "fuzzy_like_this" => [
        "fields" => ["title", "description"],
        "like_text" => "This query will return articles that are similar to this text :-)",
158
        "max_query_terms" : 12
159
    ]
160 161 162 163 164 165 166 167
]);

$query->all(); // gives you all the documents
// you can add facets to your search:
$query->addStatisticalFacet('click_stats', ['field' => 'visit_count']);
$query->search(); // gives you all the records + stats about the visit_count field. e.g. mean, sum, min, max etc...
```

Carsten Brandt committed
168
And there is so much more in it. "it’s endless what you can build"[¹](http://www.elasticsearch.org/)
169 170 171 172 173 174


Using the elasticsearch DebugPanel
----------------------------------

The yii2 elasticsearch extensions provides a `DebugPanel` that can be integrated with the yii debug module
175 176
and shows the executed elasticsearch queries. It also allows to run these queries
and view the results.
177

178 179
Add the following to you application config to enable it (if you already have the debug module
enabled, it is sufficient to just add the panels configuration):
180 181

```php
182 183 184 185 186 187 188 189 190 191 192 193 194
    // ...
    'bootstrap' => ['debug'],
    'modules' => [
        'debug' => [
            'class' => 'yii\\debug\\Module',
            'panels' => [
                'elasticsearch' => [
                    'class' => 'yii\\elasticsearch\\DebugPanel',
                ],
            ],
        ],
    ],
    // ...
195
```
Carsten Brandt committed
196

197
![elasticsearch DebugPanel](images/README-debug.png)
Carsten Brandt committed
198 199 200 201 202 203 204 205 206 207 208 209 210 211


Relation definitions with records whose primary keys are not part of attributes
-------------------------------------------------------------------------------

TODO


Patterns
--------

### Fetching records from different indexes/types

TODO