## File: README.md

> [!WARNING]
> There is no official Sphinx support planned for Yii3 DB. Use either [MySQL driver](https://github.com/yiisoft/db-mysql) directly or any of the clients availabe.



This extension adds [Sphinx](https://sphinxsearch.com/docs) full text search engine extension for the [Yii framework](https://www.yiiframework.com).
It supports all Sphinx features including [Real-time Indexes](https://sphinxsearch.com/docs/current.html#rt-indexes).

For license information check the [LICENSE](LICENSE.md)-file.

Documentation is at [docs/guide/README.md](docs/guide/README.md).

[](https://packagist.org/packages/yiisoft/db-sphinx)
[](https://packagist.org/packages/yiisoft/db-sphinx)
[](https://travis-ci.org/yiisoft/db-sphinx)

Requirements
------------

At least Sphinx version 2.0 is required. However, in order to use all extension features, Sphinx version 2.2.3 or
higher is required.

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

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

```shell
composer require --prefer-dist yiisoft/db-sphinx
```

Configuration
-------------

This extension interacts with Sphinx search daemon using MySQL protocol and [SphinxQL](https://sphinxsearch.com/docs/current.html#sphinxql) query language.
In order to setup Sphinx "searchd" to support MySQL protocol following configuration should be added:

```
searchd
{
    listen = localhost:9306:mysql41
    ...
}
```

To use this extension, simply add the following code in your application configuration:

```php
return [
    //....
    'components' => [
        'sphinx' => [
            'class' => Yiisoft\Db\Sphinx\Connection::class,
            'dsn' => 'mysql:host=127.0.0.1;port=9306;',
            'username' => '',
            'password' => '',
        ],
    ],
];
```

---

## File: CHANGELOG.md

# Yii Framework Sphinx full text search engine extension Change Log

## 1.0.0

- Initial release.

---

## File: composer.json

{
    "name": "yiisoft/db-sphinx",
    "description": "Yii Framework Sphinx full text search engine extension",
    "keywords": [
        "yii",
        "sphinx",
        "active-record",
        "search",
        "fulltext"
    ],
    "type": "library",
    "license": "BSD-3-Clause",
    "support": {
        "issues": "https://github.com/yiisoft/db-sphinx/issues",
        "forum": "https://www.yiiframework.com/forum/",
        "wiki": "https://www.yiiframework.com/wiki/",
        "irc": "ircs://irc.libera.chat:6697/yii",
        "source": "https://github.com/yiisoft/db-sphinx"
    },
    "authors": [
        {
            "name": "Paul Klimov",
            "email": "klimov.paul@gmail.com"
        }
    ],
    "minimum-stability": "dev",
    "require": {
        "yiisoft/yii-core": "^3.0@dev",
        "yiisoft/db": "^3.0@dev",
        "yiisoft/strings": "^3.0@dev",
        "ext-pdo": "*",
        "ext-pdo_mysql": "*",
        "yiisoft/active-record": "^3.0@dev"
    },
    "require-dev": {
        "phpunit/phpunit": "^7.3",
        "yiisoft/yii-web": "^3.0@dev",
        "yiisoft/di": "dev-master",
        "yiisoft/arrays": "^3.0@dev",
        "yiisoft/db-mysql": "dev-master",
        "yiisoft/yii-console": "dev-master",
        "yiisoft/log": "dev-master",
        "yiisoft/cache": "dev-master"
    },
    "repositories": [
        {
            "type": "composer",
            "url": "https://asset-packagist.org"
        }
    ],
    "autoload": {
        "psr-4": {
            "Yiisoft\\Db\\Sphinx\\": "src"
        }
    },
    "autoload-dev": {
        "psr-4": {
            "Yiisoft\\Db\\Sphinx\\Tests\\": "tests/"
        }
    },
    "extra": {
        "branch-alias": {
            "dev-master": "1.0.x-dev"
        }
    }
}

---

## File: LICENSE.md

Copyright © 2008 by Yii Software (<https://www.yiiframework.com/>)
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

* Redistributions of source code must retain the above copyright
  notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
  notice, this list of conditions and the following disclaimer in
  the documentation and/or other materials provided with the
  distribution.
* Neither the name of Yii Software nor the names of its
  contributors may be used to endorse or promote products derived
  from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

---

## File: .styleci.yml

preset: psr2

finder:
  exclude:
    - docs
    - vendor

---

## File: .travis.yml

language: php

php:
  - 7.2
  - 7.3

# run build against hhvm but allow them to fail
# https://docs.travis-ci.com/user/build-configuration/#Rows-That-are-Allowed-To-Fail
matrix:
  fast_finish: true

services:
  - mysql

sudo: true

# cache vendor dirs
cache:
  directories:
    - $HOME/.composer/cache

install:
  - travis_retry composer self-update && composer --version
  - export PATH="$HOME/.composer/vendor/bin:$PATH"
  - travis_retry composer install --prefer-dist --no-interaction

before_script:
  # show some versions and env information
  - mysql --version

  # initialize databases
  - travis_retry mysql -e 'CREATE DATABASE `yiitest`;';
  - tests/data/travis/sphinx-setup.sh
  - |
    if [ $TRAVIS_PHP_VERSION = '7.3' ]; then
      PHPUNIT_FLAGS="--coverage-clover=coverage.clover"
    fi

script:
  - ./vendor/bin/phpunit $PHPUNIT_FLAGS

---

## File: docs/internals.md

# Internals

## Unit testing

The package is tested with [PHPUnit](https://phpunit.de/). To run tests:

```shell
./vendor/bin/phpunit
```

## Mutation testing

The package tests are checked with [Infection](https://infection.github.io/) mutation framework with
[Infection Static Analysis Plugin](https://github.com/Roave/infection-static-analysis-plugin). To run it:

```shell
./vendor/bin/roave-infection-static-analysis-plugin
```

## Static analysis

The code is statically analyzed with [Psalm](https://psalm.dev/). To run static analysis:

```shell
./vendor/bin/psalm
```

## Rector

Use [Rector](https://github.com/rectorphp/rector) to make codebase follow some specific rules or
use either newest or any specific version of PHP:

```shell
./vendor/bin/rector
```

## Composer require checker

This package uses [composer-require-checker](https://github.com/maglnet/ComposerRequireChecker) to check if all dependencies are correctly defined in `composer.json`.

To run the checker, execute the following command:

```shell
./vendor/bin/composer-require-checker
```

---

## File: docs/guide/en/README.md

# Yii Framework Sphinx full text search engine extension

This extension adds [Sphinx](https://sphinxsearch.com/docs) full text search engine extension for the Yii 2 framework.
It supports all Sphinx features including [Real-time Indexes](https://sphinxsearch.com/docs/current.html#rt-indexes).

Getting Started
---------------

* [Installation](installation.md)
* [Basic Usage](basic-usage.md)

Usage
-----

* [Composing 'MATCH' statement](usage-match.md)
* [Using the ActiveRecord](usage-ar.md)
* [Fetching query META information](usage-meta.md)
* [Facet search](usage-facets.md)
* [Working with data providers](usage-data-providers.md)
* [Building Snippets (Excerpts)](usage-snippets.md)

Additional topics
-----------------

* [Using Gii generator](topics-gii.md)
* [Float params binding](topics-float-param-binding.md)
* [Working with distributed indexes](distributed-indexes.md)

---

## File: docs/guide/en/basic-usage.md

Basic Usage
===========

Since this extension uses MySQL protocol to access Sphinx, it shares base approach and much code from the
regular "Yiisoft\Db" package. Running SphinxQL queries a very similar to regular SQL ones:

```php
$sql = 'SELECT * FROM idx_item WHERE group_id = :group_id';
$params = [
    'group_id' => 17
];
$rows = Yii::$app->sphinx->createCommand($sql, $params)->queryAll();
```

You can also use a Query Builder:

```php
use Yiisoft\Db\Sphinx\Query;

$query = new Query();
$rows = $query->select('id, price')
    ->from('idx_item')
    ->andWhere(['group_id' => 1])
    ->all();
```

> Note: Sphinx limits the number of records returned by any query to 10 records by default.
  If you need to get more records you should specify limit explicitly.

---

## File: docs/guide/en/distributed-indexes.md

Working with distributed indexes
================================

This extension uses `DESCRIBE` query in order to fetch information about Sphinx index structure (field names and types).
However for the [distributed indexes](https://sphinxsearch.com/docs/current.html#distributed) it is not always possible.
Schema of such index can be found only, if its declaration contains at list one available local index.
For example:

```php
index item_distributed
{
    type = distributed

    # local index :
    local = item_local

    # remote indexes :
    agent = 127.0.0.1:9312:remote_item_1
    agent = 127.0.0.1:9313:remote_item_2
    # ...
}
```

It is recommended to have at least one local index in the distributed index declaration. You are not forced ot actually
use it - this local index may be empty, it is needed for the schema declaration only.

Still it is allowed to specify distributed index without local one. For such index the default dummy schema will be used.
However in this case automatic typecasting for the index fields will be unavailable and you should perform data typecast
on your own.
For example:

```php
use Yiisoft\Db\Sphinx\Query;

// distributed index with local
$rows = (new Query())->from('item_distributed_with_local')
    ->where(['category_id' => '12']) // works fine string `'12'` - converted to integer `12`
    ->all();

// distributed index without local
$rows = (new Query())->from('item_distributed_without_local')
    ->where(['category_id' => '12']) // produces SphinxQL error: 'syntax error, unexpected QUOTED_STRING, expecting CONST_INT'
    ->all();

$rows = (new Query())->from('item_distributed_without_local')
    ->where(['category_id' => (int)'12']) // need to perform typecasting
    ->all();
```

---

## File: docs/guide/en/installation.md

# Installation

## Requirements

At least Sphinx version 2.0 is required. However, in order to use all extension features, Sphinx version 2.2 or
higher is required.

## Getting Composer package

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

```shell
composer require --prefer-dist yiisoft/db-sphinx
```

## Configuration

This extension interacts with Sphinx search daemon using MySQL protocol and [SphinxQL](https://sphinxsearch.com/docs/current.html#sphinxql) query language.
In order to setup Sphinx "searchd" to support MySQL protocol following configuration should be added:

```
searchd
{
    listen = localhost:9306:mysql41
    ...
}
```

To use this extension, simply add the following code in your application configuration:

```php
return [
    //....
    'components' => [
        'sphinx' => [
            'class' => Yiisoft\Db\Sphinx\Connection::class,
            'dsn' => 'mysql:host=127.0.0.1;port=9306;',
            'username' => '',
            'password' => '',
        ],
    ],
];
```

---

## File: docs/guide/en/topics-float-param-binding.md

Float params binding
====================

There are issue related to float values binding using PDO and SphinxQL.
PDO does not provide a way to bind a float parameter in prepared statement mode, thus float values are passed
with mode `PDO::PARAM_STR` and thus are bound to the statement as quoted strings, e.g. `'9.85'`.
Unfortunally, SphinxQL is unable to recognize float values passed in this way, producing following error:

> syntax error, unexpected QUOTED_STRING, expecting CONST_INT or CONST_FLOAT

In order to bypass this problem any parameter bind to the [[\Yiisoft\Db\Sphinx\Command]], which PHP type is exactly 'float',
will be inserted to the SphinxQL content as literal instead of being bound.

This feature works only if value is a native PHP float (strings containing floats do not work).
For example:

```php
use Yiisoft\Db\Sphinx\Query;

// following code works fine:
$rows = (new Query())->from('item_index')
    ->where('price > :price AND price < :priceMax', [
        'price' => 2.1,
        'priceMax' => 2.9,
    ])
    ->all();

// this one produces an error:
$rows = (new Query())->from('item_index')
    ->where('price > :price AND price < :priceMax', [
        'price' => '2.1',
        'priceMax' => '2.9',
    ])
    ->all();
```

However, in case you are using 'hash' conditions over the index fields declared as 'float', the type conversion will be
performed automatically:

```php
use Yiisoft\Db\Sphinx\Query;

// following code works fine in case 'price' is a float field in 'item_index':
$rows = (new Query())->from('item_index')
    ->where([
        'price' => '2.5'
    ])
    ->all();
```

> Note: it could be by the time you are reading this float param binding is already fixed at Sphinx server side, or there
  are other concerns about this functionality, which make it undesirable. In this case you can disable automatic
  float params conversion via [[\Yiisoft\Db\Sphinx\Connection::enableFloatConversion]].

---

## File: docs/guide/en/topics-gii.md

Using Gii generator
===================

This extension provides a code generator, which can be integrated with yii 'gii' module. It allows generation of the
Active Record code. In order to enable it, you should adjust your application configuration in following way:

```php
return [
    //....
    'modules' => [
        // ...
        'gii' => [
            'class' => 'Yiisoft\Yii\Gii\Module',
            'generators' => [
                'sphinxModel' => [
                    'class' => 'Yiisoft\Db\Sphinx\gii\model\Generator'
                ]
            ],
        ],
    ]
];
```

---

## File: docs/guide/en/usage-ar.md

Using the ActiveRecord
======================

This extension provides ActiveRecord solution similar ot the [[\Yiisoft\Db\ActiveRecord]].
To declare an ActiveRecord class you need to extend [[\Yiisoft\Db\Sphinx\ActiveRecord]] and
implement the `indexName` method:

```php
use Yiisoft\Db\Sphinx\ActiveRecord;

class Article extends ActiveRecord
{
    /**
     * @return string the name of the index associated with this ActiveRecord class.
     */
    public static function indexName()
    {
        return 'idx_article';
    }
}
```

---

## File: docs/guide/en/usage-data-providers.md

Working with data providers
===========================

You can use [[\yii\data\ActiveDataProvider]] with the [[\Yiisoft\Db\Sphinx\Query]] and [[\Yiisoft\Db\Sphinx\ActiveQuery]]:

```php
use yii\data\ActiveDataProvider;
use Yiisoft\Db\Sphinx\Query;

$query = new Query();
$query->from('yii2_test_article_index')->match('development');
$provider = new ActiveDataProvider([
    'query' => $query,
    'pagination' => [
        'pageSize' => 10,
    ]
]);
$models = $provider->getModels();
```

```php
use yii\data\ActiveDataProvider;
use app\models\Article;

$provider = new ActiveDataProvider([
    'query' => Article::find(),
    'pagination' => [
        'pageSize' => 10,
    ]
]);
$models = $provider->getModels();
```

However, if you want to use ['facet' feature](usage-facets.md) or [query meta information](usage-meta.md) benefit
you need to use `Yiisoft\Db\Sphinx\ActiveDataProvider`. It allows preparing total item count using query 'meta' information
and fetching of the facet results:

```php
use Yiisoft\Db\Sphinx\ActiveDataProvider;
use Yiisoft\Db\Sphinx\Query;

$query = new Query();
$query->from('idx_item')
    ->match('foo')
    ->showMeta(true)
    ->facets([
        'brand_id',
        'categories',
    ]);
$provider = new ActiveDataProvider([
    'query' => $query,
    'pagination' => [
        'pageSize' => 10,
    ]
]);
$models = $provider->getModels();
$facets = $provider->getFacets();
$brandIdFacet = $provider->getFacet('brand_id');
```

> Note: Because pagination offset and limit may exceed Sphinx 'max_matches' bounds, data provider will set 'max_matches'
  option automatically based on those values. However, if [[Query::showMeta]] is set, such adjustment is not performed
  as it will break total count calculation, so you'll have to deal with 'max_matches' bounds on your own.

---

## File: docs/guide/en/usage-facets.md

Facet search
============

Since version 2.2.3 Sphinx provides ability of the facet searching via `FACET` clause:

```
SELECT * FROM idx_item FACET brand_id FACET categories;
```

`Yiisoft\Db\Sphinx\Query` supports composition of this clause as well as fetching facet results.
You may specify facets via `Yiisoft\Db\Sphinx\Query::facets`. In order to fetch results with facets you need
to use `Yiisoft\Db\Sphinx\Query::search()` method.
For example:

```php
use Yiisoft\Db\Sphinx\Query;

$query = new Query();
$results = $query->from('idx_item')
    ->facets([
        'brand_id',
        'categories',
    ])
    ->search($connection); // retrieve all rows and facets

$items = $results['hits'];
$facets = $results['facets'];

foreach ($results['facets']['brand_id'] as $frame) {
    $brandId = $frame['value'];
    $count = $frame['count'];
    ...
}
```

> Note: make sure you are using Sphinx server version 2.2.3 or higher before attempting to use facet feature.

You may specify additional facet options like `select` or `order` using an array format:

```php
use Yiisoft\Db\Expression;
use Yiisoft\Db\Sphinx\Query;

$query = new Query();
$results = $query->from('idx_item')
    ->facets([
        'price' => [
            'select' => 'INTERVAL(price,200,400,600,800) AS price', // using function
            'order' => ['FACET()' => SORT_ASC],
        ],
        'name_in_json' => [
            'select' => [new Expression('json_attr.name AS name_in_json')], // have to use `Expression` to avoid unnecessary quoting
        ],
    ])
    ->search($connection);
```

> Note: if you specify a custom select for a facet, ensure the facet name has the corresponding column inside the select statement.
  For example, if you have specified a facet named 'my_facet', its select statement should contain 'my_facet' attribute or
  an expression aliased as 'my_facet' ('expr() AS my_facet').

---

## File: docs/guide/en/usage-match.md

Composing 'MATCH' statement
===========================

Sphinx usage does not make sense unless you are using its fulltext search ability.
In SphinxQL it is provided via 'MATCH' statement. You can always compose it manually as a part of the 'where'
condition, but if you are using `Yiisoft\Db\Sphinx\Query` you can do it via `Yiisoft\Db\Sphinx\Query::match()`:

```php
use Yiisoft\Db\Sphinx\Query;

$query = new Query();
$rows = $query->from('idx_item')
    ->match($_POST['search'])
    ->all();
```

Please note that Sphinx 'MATCH' statement argument uses complex internal syntax for better tuning.
By default `Yiisoft\Db\Sphinx\Query::match()` will escape all special characters related to this syntax from
its argument. So if you wish to use complex 'MATCH' statement, you should use `Yiisoft\Db\Expression` for it:

```php
use Yiisoft\Db\Sphinx\Query;
use Yiisoft\Db\Expression;

$query = new Query();
$rows = $query->from('idx_item')
    ->match(new Expression(':match', ['match' => '@(content) ' . Yii::$app->sphinx->escapeMatchValue($_POST['search'])]))
    ->all();
```

> Note: if you compose 'MATCH' argument, make sure to use `\Yiisoft\Db\Sphinx\Connection::escapeMatchValue()` to properly
  escape any special characters, which may break the query.

Since version 2.0.6 you can use [[\Yiisoft\Db\Sphinx\MatchExpression]] for the 'MATCH' statement composition.
It allows composition of the 'MATCH' expression using placeholders in similar way as bound parameters, which
values will be automatically escaped using [[\Yiisoft\Db\Sphinx\Connection::escapeMatchValue()]].
For examples:

```php
use Yiisoft\Db\Sphinx\Query;
use Yiisoft\Db\Sphinx\MatchExpression;

$rows = (new Query())
    ->match(new MatchExpression('@title :title', ['title' => 'Yii'])) // value of ':title' will be escaped automatically
    ->all();
```

You may use [[match()]], [[andMatch()]] and [[orMatch()]] to combine several conditions.
Each condition can be specified using array syntax similar to the one used for [[\Yiisoft\Db\Sphinx\Query:where]].
For example:

```php
use Yiisoft\Db\Sphinx\Query;
use Yiisoft\Db\Sphinx\MatchExpression;

$rows = (new Query())
    ->match(
        // produces '((@title "Yii") (@author "Paul")) | (@content "Sphinx")' :
        (new MatchExpression())
            ->match(['title' => 'Yii'])
            ->andMatch(['author' => 'Paul'])
            ->orMatch(['content' => 'Sphinx'])
    )
    ->all();
```

You may as well compose expressions with special operators like 'MAYBE', 'PROXIMITY' etc.
For example:

```php
use Yiisoft\Db\Sphinx\Query;
use Yiisoft\Db\Sphinx\MatchExpression;

$rows = (new Query())
    ->match(
        // produces '@title "Yii" MAYBE "Sphinx"' :
        (new MatchExpression())->match([
            'maybe',
            'title',
            'Yii',
            'Sphinx',
        ])
    )
    ->all();

$rows = (new Query())
    ->match(
        // produces '@title "Yii"~10' :
        (new MatchExpression())->match([
            'proximity',
            'title',
            'Yii',
            10,
        ])
    )
    ->all();
```

---

## File: docs/guide/en/usage-meta.md

Fetching query META information
===============================

Sphinx allows fetching statistical information about last performed query via [SHOW META](https://sphinxsearch.com/docs/current.html#sphinxql-show-meta) SphinxQL statement.
This information is commonly used to get total count of rows in the index without extra `SELECT COUNT(*) ...` query.
Although you can always run such query manually, `Yiisoft\Db\Sphinx\Query` allows you to do this automatically without extra efforts.
All you need to do is enable `Yiisoft\Db\Sphinx\Query::showMeta` and use `Yiisoft\Db\Sphinx\Query::search()` to fetch all rows and
meta information:

```php
$query = new Query();
$results = $query->from('idx_item')
    ->match('foo')
    ->showMeta(true) // enable automatic 'SHOW META' query
    ->search(); // retrieve all rows and META information

$items = $results['hits'];
$meta = $results['meta'];
$totalItemCount = $results['meta']['total'];
```

> Note: Total item count that can be extracted from 'meta' is limited to `max_matches` sphinx option.
  If your index contains more records than `max_matches` value (usually - 1000), you should either raise up
  `max_matches` via [[Query::options]] or use [[Query::count()]] to retrieve records count.

---

## File: docs/guide/en/usage-snippets.md

Building Snippets (Excerpts)
============================

Snippet (excerpt) - is a fragment of the index source text, which contains highlighted words from fulltext search
condition. Sphinx has a powerful build-in mechanism to compose snippets. However, since Sphinx does not store the
original indexed text, the snippets for the rows in query result should be build separately via another query.
Such query may be performed via `Yiisoft\Db\Sphinx\Command::callSnippets()`:

```php
$sql = "SELECT * FROM idx_item WHERE MATCH('about')";
$rows = Yii::$app->sphinx->createCommand($sql)->queryAll();

$rowSnippetSources = [];
foreach ($rows as $row) {
    $rowSnippetSources[] = file_get_contents('/path/to/index/files/' . $row['id'] . '.txt');
}

$snippets = Yii::$app->sphinx->createCommand($sql)->callSnippets('idx_item', $rowSnippetSources, 'about');
```

You can simplify this workflow using [[Yiisoft\Db\Sphinx\Query::snippetCallback]].
It is a PHP callback, which receives array of query result rows as an argument and must return the
array of snippet source strings in the order, which match one of incoming rows.
Example:

```php
use Yiisoft\Db\Sphinx\Query;

$query = new Query();
$rows = $query->from('idx_item')
    ->match($_POST['search'])
    ->snippetCallback(function ($rows) {
        $result = [];
        foreach ($rows as $row) {
            $result[] = file_get_contents('/path/to/index/files/' . $row['id'] . '.txt');
        }
        return $result;
    })
    ->all();

foreach ($rows as $row) {
    echo $row['snippet'];
}
```

If you are using Active Record, you can [[Yiisoft\Db\Sphinx\ActiveQuery::snippetByModel()]] to compose a snippets.
This method retrieves snippet source per each row calling `getSnippetSource()` method of the result model.
All you need to do is implement it in your Active Record class, so it return the correct value:

```php
use Yiisoft\Db\Sphinx\ActiveRecord;

class Article extends ActiveRecord
{
    public function getSnippetSource()
    {
        return file_get_contents('/path/to/source/files/' . $this->id . '.txt');;
    }
}

$articles = Article::find()->snippetByModel()->all();

foreach ($articles as $article) {
    echo $article->snippet;
}
```

---

## File: docs/guide/ja/README.md

Yii 2 Sphinx エクステンション
=============================

このエクステンションは Yii 2 フレームワークに [Sphinx](https://sphinxsearch.com/docs) 全文検索エンジンのサポートを追加します。
このエクステンションは、[実行時インデックス](https://sphinxsearch.com/docs/current.html#rt-indexes) も含めて、Sphinx の全ての機能をサポートしています。

始めよう
--------

* [インストール](installation.md)
* [基本的な使用方法](basic-usage.md)

使用方法
--------

* ['MATCH' 文を作成する](usage-match.md)
* [アクティブレコードを使用する](usage-ar.md)
* [クエリのメタ情報を取得する](usage-meta.md)
* [ファセット検索](usage-facets.md)
* [データプロバイダを扱う](usage-data-providers.md)
* [スニペット (抜粋) を構築する](usage-snippets.md)

追加のトピック
--------------

* [Gii ジェネレータを使用する](topics-gii.md)
* [Float params binding](topics-float-param-binding.md)
* [Working with distributed indexes](distributed-indexes.md)

---

## File: docs/guide/ja/basic-usage.md

[Binary file]

---

## File: docs/guide/ja/distributed-indexes.md

Working with distributed indexes
================================

This extension uses `DESCRIBE` query in order to fetch information about Sphinx index structure (field names and types).
However for the [distributed indexes](https://sphinxsearch.com/docs/current.html#distributed) it is not always possible.
Schema of such index can be found only, if its declaration contains at list one available local index.
For example:

```php
index item_distributed
{
    type = distributed

    # local index :
    local = item_local

    # remote indexes :
    agent = 127.0.0.1:9312:remote_item_1
    agent = 127.0.0.1:9313:remote_item_2
    # ...
}
```

It is recommended to have at least one local index in the distributed index declaration. You are not forced ot actually
use it - this local index may be empty, it is needed for the schema declaration only.

Still it is allowed to specify distributed index without local one. For such index the default dummy schema will be used.
However in this case automatic typecasting for the index fields will be unavailable and you should perform data typecast
on your own.
For example:

```php
use Yiisoft\Db\Sphinx\Query;

// distributed index with local
$rows = (new Query())->from('item_distributed_with_local')
    ->where(['category_id' => '12']) // works fine string `'12'` - converted to integer `12`
    ->all();

// distributed index without local
$rows = (new Query())->from('item_distributed_without_local')
    ->where(['category_id' => '12']) // produces SphinxQL error: 'syntax error, unexpected QUOTED_STRING, expecting CONST_INT'
    ->all();

$rows = (new Query())->from('item_distributed_without_local')
    ->where(['category_id' => (int)'12']) // need to perform typecasting
    ->all();
```

---

## File: docs/guide/ja/installation.md

インストール
============

## 必要条件

最低限の必要条件は、Sphinx バージョン 2.0 です。
ただし、エクステンションの全ての機能を使用するためには、Sphinx バージョン 2.2 以降が必要になります。

## Composer パッケージを取得する

このエクステンションをインストールするのに推奨される方法は [composer](https://getcomposer.org/download/) によるものです。

下記のコマンドを実行してください。

```
php composer.phar require --prefer-dist yiisoft/db-sphinx
```

または、あなたの `composer.json` ファイルの `require` セクションに、下記を追加してください。

```
"yiisoft/db-sphinx": "~1.0.0"
```

## 構成

このエクステンションは、MySQL プロトコルと [SphinxQL](https://sphinxsearch.com/docs/current.html#sphinxql) クエリ言語を使用して Sphinx 検索デーモンとやりとりをします。
Sphinx の "searchd" が MySQL プロトコルをサポートするように設定するために、下記の構成情報を追加しなければなりません。

```
searchd
{
    listen = localhost:9306:mysql41
    ...
}
```

そして、このエクステンションを使用するために、アプリケーションの構成情報に下記のコードを追加します。

```php
return [
    //....
    'components' => [
        'sphinx' => [
            'class' => 'Yiisoft\Db\Sphinx\Connection',
            'dsn' => 'mysql:host=127.0.0.1;port=9306;',
            'username' => '',
            'password' => '',
        ],
    ],
];
```

---

## File: docs/guide/ja/topics-float-param-binding.md

Float params binding
====================

There are issue related to float values binding using PDO and SphinxQL.
PDO does not provide a way to bind a float parameter in prepared statement mode, thus float values are passed
with mode `PDO::PARAM_STR` and thus are bound to the statement as quoted strings, e.g. `'9.85'`.
Unfortunally, SphinxQL is unable to recognize float values passed in this way, producing following error:

> syntax error, unexpected QUOTED_STRING, expecting CONST_INT or CONST_FLOAT

In order to bypass this problem any parameter bind to the [[\Yiisoft\Db\Sphinx\Command]], which PHP type is exactly 'float',
will be inserted to the SphinxQL content as literal instead of being bound.

This feature works only if value is a native PHP float (strings containing floats do not work).
For example:

```php
use Yiisoft\Db\Sphinx\Query;

// following code works fine:
$rows = (new Query())->from('item_index')
    ->where('price > :price AND price < :priceMax', [
        'price' => 2.1,
        'priceMax' => 2.9,
    ])
    ->all();

// this one produces an error:
$rows = (new Query())->from('item_index')
    ->where('price > :price AND price < :priceMax', [
        'price' => '2.1',
        'priceMax' => '2.9',
    ])
    ->all();
```

However, in case you are using 'hash' conditions over the index fields declared as 'float', the type conversion will be
performed automatically:

```php
use Yiisoft\Db\Sphinx\Query;

// following code works fine in case 'price' is a float field in 'item_index':
$rows = (new Query())->from('item_index')
    ->where([
        'price' => '2.5'
    ])
    ->all();
```

> Note: it could be by the time you are reading this float param binding is already fixed at Sphinx server side, or there
  are other concerns about this functionality, which make it undesirable. In this case you can disable automatic
  float params conversion via [[\Yiisoft\Db\Sphinx\Connection::enableFloatConversion]].

---

## File: docs/guide/ja/topics-gii.md

Gii ジェネレータを使用する
==========================

このエクステンションは Yii の 'gii' モジュールと統合できるコードジェネレータを提供しています。
これはアクティブレコードのコードを生成することが出来るものです。
これを有効にするためには、あなたのアプリケーションの構成情報を以下のように修正しなければなりません。

```php
return [
    //....
    'modules' => [
        // ...
        'gii' => [
            'class' => 'Yiisoft\Yii\Gii\Module',
            'generators' => [
                'sphinxModel' => [
                    'class' => 'Yiisoft\Db\Sphinx\gii\model\Generator'
                ]
            ],
        ],
    ]
];
```

---

## File: docs/guide/ja/usage-ar.md

アクティブレコードを使用する
============================

このエクステンションは [[\Yiisoft\Db\ActiveRecord]] と類似したアクティブレコードのソリューションを提供しています。
アクティブレコードクラスを宣言するためには、[[\Yiisoft\Db\Sphinx\ActiveRecord]] から拡張して、`indexName` メソッドを実装する必要があります。

```php
use Yiisoft\Db\Sphinx\ActiveRecord;

class Article extends ActiveRecord
{
    /**
     * @return string このアクティブレコードクラスと関連付けられた index の名前
     */
    public static function indexName()
    {
        return 'idx_article';
    }
}
```

---

## File: docs/guide/ja/usage-data-providers.md

データプロバイダを扱う
======================

[[\Yiisoft\Db\Sphinx\Query]] および [[\Yiisoft\Db\Sphinx\ActiveQuery]] とともに [[\yii\data\ActiveDataProvider]] を使うことが出来ます。

```php
use yii\data\ActiveDataProvider;
use Yiisoft\Db\Sphinx\Query;

$query = new Query();
$query->from('yii2_test_article_index')->match('development');
$provider = new ActiveDataProvider([
    'query' => $query,
    'pagination' => [
        'pageSize' => 10,
    ]
]);
$models = $provider->getModels();
```

```php
use yii\data\ActiveDataProvider;
use app\models\Article;

$provider = new ActiveDataProvider([
    'query' => Article::find(),
    'pagination' => [
        'pageSize' => 10,
    ]
]);
$models = $provider->getModels();
```

しかし、[ファセットの機能](usage-facets.md) または [クエリのメタ情報](usage-meta.md) を利用したい場合は、`Yiisoft\Db\Sphinx\ActiveDataProvider` を使用する必要があります。
これを使えば、クエリのメタ情報を使ってアイテムの総数を準備したり、ファセット検索の結果を取得したりすることが出来ます。

```php
use Yiisoft\Db\Sphinx\ActiveDataProvider;
use Yiisoft\Db\Sphinx\Query;

$query = new Query();
$query->from('idx_item')
    ->match('foo')
    ->showMeta(true)
    ->facets([
        'brand_id',
        'categories',
    ]);
$provider = new ActiveDataProvider([
    'query' => $query,
    'pagination' => [
        'pageSize' => 10,
    ]
]);
$models = $provider->getModels();
$facets = $provider->getFacets();
$brandIdFacet = $provider->getFacet('brand_id');
```
> Note: ページネーションのオフセットとリミットが Sphinx の 'max_matches' の境界を超える可能性があるため、データプロバイダはそれらの値に基づいて 'max_matches' オプションを自動的に設定します。
ただし、[[Query::showMeta]] が設定されている場合は、総数の計算結果を損なうことになるため、そのような調整は実行されませんので、あなた自身が 'max_matches' の境界を操作しなければなりません。

---

## File: docs/guide/ja/usage-facets.md

[Binary file]

---

## File: docs/guide/ja/usage-match.md

'MATCH' 文を作成する
====================

全文検索の能力を使用するのでなければ、Sphinx を使用しても意味がありません。
SphinxQL では、全文検索の機能は 'MATCH' 文によって提供されています。
'MATCH' 文は、いつでも 'where' 条件の一部として手動で作成することが出来ますが、`Yiisoft\Db\Sphinx\Query` を使うのであれば `Yiisoft\Db\Sphinx\Query::match()` によって作成することが出来ます。

```php
use Yiisoft\Db\Sphinx\Query;

$query = new Query();
$rows = $query->from('idx_item')
    ->match($_POST['search'])
    ->all();
```

Sphinx は、検索のより良いチューニングのために、'MATCH' 文の引数に、複雑な内部的構文を使用することに注意してください。
デフォルトでは、`Yiisoft\Db\Sphinx\Query::match()` の引数の中の、内部的構文に関わる全ての特殊文字がエスケープされます。
従って、複雑な 'MATCH' 文を使用したい場合は、引数のために `Yiisoft\Db\Expression` を使わなければなりません。

```php
use Yiisoft\Db\Sphinx\Query;
use Yiisoft\Db\Expression;

$query = new Query();
$rows = $query->from('idx_item')
    ->match(new Expression(':match', ['match' => '@(content) ' . Yii::$app->sphinx->escapeMatchValue($_POST['search'])]))
    ->all();
```

> Note: 'MATCH' の引数を作成する場合は、必ず `Yiisoft\Db\Sphinx\Connection::escapeMatchValue()` を使って全ての特殊文字を適切にエスケープしてください。
  そうしないと、クエリが破壊されます。

バージョン 2.0.6 以降は、'MATCH' 文の作成に [[\Yiisoft\Db\Sphinx\MatchExpression]] を使うことが出来ます。
これを使うと、パラメータバインディングと同じ方法のプレースホルダを使うことが出来、引数の値が [[\Yiisoft\Db\Sphinx\Connection::escapeMatchValue()]] を使って自動的にエスケープされるようになります。
例えば、

```php
use Yiisoft\Db\Sphinx\Query;
use Yiisoft\Db\Sphinx\MatchExpression;

$rows = (new Query())
    ->match(new MatchExpression('@title :title', ['title' => 'Yii'])) // ':title' の値が自動的にエスケープされる
    ->all();
```

[[match()]]、[[andMatch()]] および [[orMatch()]] を使って、複数の条件を結合することが出来ます。
各条件は、[[\Yiisoft\Db\Sphinx\Query:where]] で使われているのと同じ配列構文を使って指定することが出来ます。
例えば、

```php
use Yiisoft\Db\Sphinx\Query;
use Yiisoft\Db\Sphinx\MatchExpression;

$rows = (new Query())
    ->match(
        // '((@title "Yii") (@author "Paul")) | (@content "Sphinx")' を生成
        (new MatchExpression())
            ->match(['title' => 'Yii'])
            ->andMatch(['author' => 'Paul'])
            ->orMatch(['content' => 'Sphinx'])
    )
    ->all();
```

'MAYBE'、'PROXIMITY' など、特殊な演算子を使って式を作成することも可能です。
例えば、

```php
use Yiisoft\Db\Sphinx\Query;
use Yiisoft\Db\Sphinx\MatchExpression;

$rows = (new Query())
    ->match(
        // '@title "Yii" MAYBE "Sphinx"' を生成
        (new MatchExpression())->match([
            'maybe',
            'title',
            'Yii',
            'Sphinx',
        ])
    )
    ->all();

$rows = (new Query())
    ->match(
        // '@title "Yii"~10' を生成
        (new MatchExpression())->match([
            'proximity',
            'title',
            'Yii',
            10,
        ])
    )
    ->all();
```

---

## File: docs/guide/ja/usage-meta.md

クエリのメタ情報を取得する
==========================

Sphinx では、[SHOW META](https://sphinxsearch.com/docs/current.html#sphinxql-show-meta) SphinxQL 文によって、最後に実行されたクエリの統計的な情報を取得することが出来ます。
この情報は、通常、追加の `SELECT COUNT(*) ...` クエリを発行せずにインデックス中の総行数を取得するのに使用されます。
`SHOW META` のクエリは何時でも手動で実行することが出来ますが、`Yiisoft\Db\Sphinx\Query` を使えば、余計な労力を費やさずとも、自動でこれを実行することが出来ます。
必要なことは、`Yiisoft\Db\Sphinx\Query::showMeta` を有効にして、`Yiisoft\Db\Sphinx\Query::search()` を使って全ての行とメタ情報を取得することだけです。

```php
$query = new Query();
$results = $query->from('idx_item')
    ->match('foo')
    ->showMeta(true) // 自動の 'SHOW META' クエリを有効にする
    ->search(); // 全ての行とメタ情報を取得する

$items = $results['hits'];
$meta = $results['meta'];
$totalItemCount = $results['meta']['total'];
```

> Note: 'meta' から抽出可能な総アイテム数は Sphinx の `max_matches` オプションの値に制限されることに注意してください。
  あなたのインデックスが `max_matches` の値 (通常は 1000 以下) を超えるレコードを含んでいる場合は、レコード数を取得するためには、[[Query::options]] によって `max_matches` を引き上げるか、または [[Query::count()]] を使わなければなりません。

---

## File: docs/guide/ja/usage-snippets.md

スニペット (抜粋) を構築する
============================

スニペット (抜粋) はインデックスされたソーステキストの断片で、全文検索の条件に従ってハイライトされた言葉を含むものです。
Sphinx はスニペットを構築する強力なメカニズムを内蔵しています。
しかしながら、Sphinx はオリジナルのインデックスされたテキストを保存しないため、クエリ結果に含まれる行に対するスニペットは、独立した別のクエリによって構築されなければなりません。
そのようなクエリを `Yiisoft\Db\Sphinx\Command::callSnippets()` によって実行することが出来ます。

```php
$sql = "SELECT * FROM idx_item WHERE MATCH('about')";
$rows = Yii::$app->sphinx->createCommand($sql)->queryAll();

$rowSnippetSources = [];
foreach ($rows as $row) {
    $rowSnippetSources[] = file_get_contents('/path/to/index/files/' . $row['id'] . '.txt');
}

$snippets = Yii::$app->sphinx->createCommand($sql)->callSnippets('idx_item', $rowSnippetSources, 'about');
```

このワークフローは、[[Yiisoft\Db\Sphinx\Query::snippetCallback]] を使って、単純化することが出来ます。
これは、クエリ結果の行の配列を引数として取り、入力された行の順序にしたがってスニペットのソース文字列の配列を返す PHP コールバックです。
例えば、

```php
use Yiisoft\Db\Sphinx\Query;

$query = new Query();
$rows = $query->from('idx_item')
    ->match($_POST['search'])
    ->snippetCallback(function ($rows) {
        $result = [];
        foreach ($rows as $row) {
            $result[] = file_get_contents('/path/to/index/files/' . $row['id'] . '.txt');
        }
        return $result;
    })
    ->all();

foreach ($rows as $row) {
    echo $row['snippet'];
}
```

アクティブレコードを使う場合は、[[Yiisoft\Db\Sphinx\ActiveQuery::snippetByModel()]] を使ってスニペットを構築することが出来ます。
このメソッドは、検索結果であるモデルの `getSnippetSource()` メソッドを呼ぶことによって、各行ごとにスニペットのソースを取得します。
必要なことは、あなたのアクティブレコードクラスにおいて、正しい値を返すように `getSnippetSource()` メソッドを実装することだけです。

```php
use Yiisoft\Db\Sphinx\ActiveRecord;

class Article extends ActiveRecord
{
    public function getSnippetSource()
    {
        return file_get_contents('/path/to/source/files/' . $this->id . '.txt');
    }
}

$articles = Article::find()->snippetByModel()->all();

foreach ($articles as $article) {
    echo $article->snippet;
}
```

---

## File: docs/guide/ru/README.md

Расширение Sphinx для Yii 2
==========================

Это расширение добавляет полнотекстовый поисковый движок [Sphinx](https://sphinxsearch.com/docs) для фреймворка Yii 2.
Он поддерживает все функции Sphinx, включая [Real-time индексы](https://sphinxsearch.com/docs/current.html#rt-indexes).

Как начать
---------------

* [Установка](installation.md)
* [Базовое использование](basic-usage.md)

Использование
-----

* [Составление инструкции 'MATCH'](usage-match.md)
* [Использование ActiveRecord](usage-ar.md)
* [Извлечение META информации](usage-meta.md)
* [Фасетный поиск](usage-facets.md)
* [Работа с провайдерами данных](usage-data-providers.md)
* [Создание снипетов (Выдержки)](usage-snippets.md)

Дополнительно
-----------------

* [Использование генератора Gii](topics-gii.md)
* [Связывание параметров с плавающей точкой](topics-float-param-binding.md)
* [Работа с распределенными индексами](distributed-indexes.md)

---

## File: docs/guide/ru/basic-usage.md

Базовое использование
===========

Поскольку это расширение использует протокол MySQL для доступа к Sphinx, оно разделяет базовый подход и множество кода из регулярного пакета `"Yiisoft\Db"`. Запуск запросов SphinxQL очень похож на обычные SQL-запросы:

```php
$sql = 'SELECT * FROM idx_item WHERE group_id = :group_id';
$params = [
    'group_id' => 17
];
$rows = Yii::$app->sphinx->createCommand($sql, $params)->queryAll();
```

Вы, также, можете использовать Query Builder:

```php
use Yiisoft\Db\Sphinx\Query;

$query = new Query();
$rows = $query->select('id, price')
    ->from('idx_item')
    ->andWhere(['group_id' => 1])
    ->all();
```

> Note: Sphinx, по умолчанию, ограничивает количество записей, возвращаемых любым запросом, до 10. Если вам нужно получить больше записей, вам следует явно указать ограничение.

---

## File: docs/guide/ru/distributed-indexes.md

[Binary file]

---

## File: docs/guide/ru/installation.md

[Binary file]

---

## File: docs/guide/ru/topics-float-param-binding.md

Связывание параметров с плавающей точкой
====================

Существуют проблемы, связанные с привязкой значений float используя PDO и SphinxQL.
PDO не предоставляет способ привязки параметра float в режиме подготовленных операторов, поэтому значения float передаются в режиме `PDO::PARAM_STR` и, таким образом, привязаны к оператору в виде цитируемых строк, например `'9.85'`. К сожалению, SphinxQL не может распознать значения float, переданные таким образом, создавая следующую ошибку:

> syntax error, unexpected QUOTED_STRING, expecting CONST_INT or CONST_FLOAT

Чтобы обойти эту проблему, любой параметр связывается с [[\Yiisoft\Db\Sphinx\Command]], какой точно PHP тип 'float' будет вставляться в содержимое SphinxQL как литерал вместо привязки.

Эта функция работает только в том случае, если значение является оригинальным PHP float (строки, содержащие float, не работают).
Например:

```php
use Yiisoft\Db\Sphinx\Query;

// следующий код работает отлично:
$rows = (new Query())->from('item_index')
    ->where('price > :price AND price < :priceMax', [
        'price' => 2.1,
        'priceMax' => 2.9,
    ])
    ->all();

//это приведет к ошибке:
$rows = (new Query())->from('item_index')
    ->where('price > :price AND price < :priceMax', [
        'price' => '2.1',
        'priceMax' => '2.9',
    ])
    ->all();
```

Однако, если вы используете 'hash' условия над полями индекса, объявленными как 'float', преобразование типа будет выполняется автоматически:

```php
use Yiisoft\Db\Sphinx\Query;

// следующий код работает отлично, если 'price' - это поле float в 'item_index':
$rows = (new Query())->from('item_index')
    ->where([
        'price' => '2.5'
    ])
    ->all();
```

> Note: к тому моменту, когда вы это читаете, эта привязка к float, может быть уже исправлена на стороне сервера Sphinx, или другие опасения по поводу этой функции, что делает ее нежелательной. В этом случае вы можете отключить автоматическое преобразование параметров float через
[[\Yiisoft\Db\Sphinx\Connection::enableFloatConversion]].

---

## File: docs/guide/ru/topics-gii.md

Использование генератора Gii
===================

Это расширение предоставляет генератор кода, который может быть интегрирован с модулем yii 'gii'. Оно позволяет генерировать Active Record код. Чтобы включить его, вы должны настроить вашу конфигурацию приложения следующим образом:

```php
return [
    //....
    'modules' => [
        // ...
        'gii' => [
            'class' => 'Yiisoft\Yii\Gii\Module',
            'generators' => [
                'sphinxModel' => [
                    'class' => 'Yiisoft\Db\Sphinx\gii\model\Generator'
                ]
            ],
        ],
    ]
];
```

---

## File: docs/guide/ru/usage-ar.md

Использование ActiveRecord
======================

Это расширение предоставляет ActiveRecord решение, подобное [[\Yiisoft\Db\ActiveRecord]].
Чтобы объявить класс ActiveRecord, вам нужно расширить [[\Yiisoft\Db\Sphinx\ActiveRecord]] и реализовать метод `indexName`:

```php
use Yiisoft\Db\Sphinx\ActiveRecord;

class Article extends ActiveRecord
{
    /**
     * @return string the name of the index associated with this ActiveRecord class.
     */
    public static function indexName()
    {
        return 'idx_article';
    }
}
```

---

## File: docs/guide/ru/usage-data-providers.md

Работа с провайдерами данных
===========================

Вы можете использовать [[\yii\data\ActiveDataProvider]] с [[\Yiisoft\Db\Sphinx\Query]] и [[\Yiisoft\Db\Sphinx\ActiveQuery]]:

```php
use yii\data\ActiveDataProvider;
use Yiisoft\Db\Sphinx\Query;

$query = new Query();
$query->from('yii2_test_article_index')->match('development');
$provider = new ActiveDataProvider([
    'query' => $query,
    'pagination' => [
        'pageSize' => 10,
    ]
]);
$models = $provider->getModels();
```

```php
use yii\data\ActiveDataProvider;
use app\models\Article;

$provider = new ActiveDataProvider([
    'query' => Article::find(),
    'pagination' => [
        'pageSize' => 10,
    ]
]);
$models = $provider->getModels();
```

Однако, если вы хотите использовать преимущества ['facet'](usage-facets.md) или [мета-информацию запроса](usage-meta.md) вам нужно использовать `Yiisoft\Db\Sphinx\ActiveDataProvider`. Он позволяет подготовить общее количество элементов с помощью 'meta' информации запроса и получить результаты фасета:

```php
use Yiisoft\Db\Sphinx\ActiveDataProvider;
use Yiisoft\Db\Sphinx\Query;

$query = new Query();
$query->from('idx_item')
    ->match('foo')
    ->showMeta(true)
    ->facets([
        'brand_id',
        'categories',
    ]);
$provider = new ActiveDataProvider([
    'query' => $query,
    'pagination' => [
        'pageSize' => 10,
    ]
]);
$models = $provider->getModels();
$facets = $provider->getFacets();
$brandIdFacet = $provider->getFacet('brand_id');
```

> Note: Поскольку смещение и ограничение нумерации страниц могут превышать границы Sphinx 'max_matches', провайдер данных установит 'max_matches'
  автоматически на основании этих значений. Однако, если [[Query::showMeta]] установлен, такая корректировка не выполняется, так как это нарушит подсчет общего количества, поэтому вам придется иметь дело с ограничениями 'max_matches' на свое усмотрение.

---

## File: docs/guide/ru/usage-facets.md

Фасетный поиск
============

Начиная с версии 2.2.3 Sphinx обеспечивает возможность фасетного поиска с помощью `FACET`:

```
SELECT * FROM idx_item FACET brand_id FACET categories;
```

`Yiisoft\Db\Sphinx\Query` поддерживает композицию этого предложения, а также выборку фасетных результатов. Вы можете указать фасеты через `Yiisoft\Db\Sphinx\Query::facets`. Чтобы получать результаты с фасетами, вам нужно использовать метод `Yiisoft\Db\Sphinx\Query::search()`.
Для примера:

```php
use Yiisoft\Db\Sphinx\Query;

$query = new Query();
$results = $query->from('idx_item')
    ->facets([
        'brand_id',
        'categories',
    ])
    ->search($connection); // получить все строки и фасеты

$items = $results['hits'];
$facets = $results['facets'];

foreach ($results['facets']['brand_id'] as $frame) {
    $brandId = $frame['value'];
    $count = $frame['count'];
    ...
}
```

> Note: убедитесь, что вы используете сервер Sphinx версии 2.2.3 или выше, прежде чем пытаться использовать особенности фасетов.

Вы можете указать дополнительные опции фасета, такие как `select` или `order` используя формат массива:

```php
use Yiisoft\Db\Expression;
use Yiisoft\Db\Sphinx\Query;

$query = new Query();
$results = $query->from('idx_item')
    ->facets([
        'price' => [
            'select' => 'INTERVAL(price,200,400,600,800) AS price', // using function
            'order' => ['FACET()' => SORT_ASC],
        ],
        'name_in_json' => [
            'select' => [new Expression('json_attr.name AS name_in_json')], // необходимо использовать `Expression`, чтобы избежать ненужного цитирования
        ],
    ])
    ->search($connection);
```

> Note: если вы укажете пользовательский выбор для фасета, убедитесь, что в названии фасета имеется соответствующий столбец внутри оператора select. Например, если вы указали фасет с именем 'my_facet', его оператор select должен содержать атрибут 'my_facet' или выражение связанное как 'my_facet' ('expr() AS my_facet').

---

## File: docs/guide/ru/usage-match.md

Составление инструкции 'MATCH'
===========================

Использование Sphinx не имеет смысла, если вы не используете его полнотекстовый поиск.
В SphinxQL он предоставляется с помощью инструкции 'MATCH'. Вы всегда можете составить его вручную как часть условия 'where', но если вы используете `Yiisoft\Db\Sphinx\Query`, вы можете сделать это через `Yiisoft\Db\Sphinx\Query::match()`:

```php
use Yiisoft\Db\Sphinx\Query;

$query = new Query();
$rows = $query->from('idx_item')
    ->match($_POST['search'])
    ->all();
```

Пожалуйста обратите внимание, что аргумент инструкции Sphinx 'MATCH' использует сложный внутренний синтаксис для лучшей настройки.
По умолчанию `Yiisoft\Db\Sphinx\Query::match()` будет избегать всех специальных символов, связанных с этим синтаксисом, из его аргумента. Поэтому, если вы хотите использовать сложный оператор 'MATCH', вы должны использовать `Yiisoft\Db\Expression` для этого:

```php
use Yiisoft\Db\Sphinx\Query;
use Yiisoft\Db\Expression;

$query = new Query();
$rows = $query->from('idx_item')
    ->match(new Expression(':match', ['match' => '@(content) ' . Yii::$app->sphinx->escapeMatchValue($_POST['search'])]))
    ->all();
```

> Note: если вы создаете аргумент 'MATCH', обязательно используйте `\Yiisoft\Db\Sphinx\Connection::escapeMatchValue()` для правильного экранирования каких-либо специальных символов, которые могут сломать запрос.

Начиная с версии 2.0.6 вы можете использовать [[\Yiisoft\Db\Sphinx\MatchExpression]] для композиции утверждения 'MATCH'.
Он позволяет создавать выражение 'MATCH' с использованием заполнителей аналогично связанным параметрам, значения которых будут автоматически экранированы с помощью [[\Yiisoft\Db\Sphinx\Connection::escapeMatchValue()]].
Например:

```php
use Yiisoft\Db\Sphinx\Query;
use Yiisoft\Db\Sphinx\MatchExpression;

$rows = (new Query())
    ->match(new MatchExpression('@title :title', ['title' => 'Yii'])) // value of ':title' will be escaped automatically
    ->all();
```

Вы можете использовать [[match()], [[andMatch()]] и [[orMatch()]] для объединения нескольких условий.
Каждое условие может быть задано с использованием синтаксиса массива, аналогичного тому, который используется для [[\Yiisoft\Db\Sphinx\Query:where]].
Например:

```php
use Yiisoft\Db\Sphinx\Query;
use Yiisoft\Db\Sphinx\MatchExpression;

$rows = (new Query())
    ->match(
        // produces '((@title "Yii") (@author "Paul")) | (@content "Sphinx")' :
        (new MatchExpression())
            ->match(['title' => 'Yii'])
            ->andMatch(['author' => 'Paul'])
            ->orMatch(['content' => 'Sphinx'])
    )
    ->all();
```

Вы также можете составлять выражения со специальными операторами, такими как 'MAYBE', 'PROXIMITY' и т.д.
Например:

```php
use Yiisoft\Db\Sphinx\Query;
use Yiisoft\Db\Sphinx\MatchExpression;

$rows = (new Query())
    ->match(
        // produces '@title "Yii" MAYBE "Sphinx"' :
        (new MatchExpression())->match([
            'maybe',
            'title',
            'Yii',
            'Sphinx',
        ])
    )
    ->all();

$rows = (new Query())
    ->match(
        // produces '@title "Yii"~10' :
        (new MatchExpression())->match([
            'proximity',
            'title',
            'Yii',
            10,
        ])
    )
    ->all();
```

---

## File: docs/guide/ru/usage-meta.md

[Binary file]

---

## File: docs/guide/ru/usage-snippets.md

Создание снипетов (Выдержки)
============================

Сниппет (выдержка) - фрагмент исходного текста индекса, который содержит выделенные слова изсостояния полнотекстового поиска. Sphinx имеет мощный встроенный механизм для создания фрагментов. Однако, поскольку Sphinx не сохраняет исходный проиндексированный текст, фрагменты для строк в результате запроса должны быть построены отдельно через другой запрос.
Такой запрос может быть выполнен с помощью `Yiisoft\Db\Sphinx\Command::callSnippets()`:

```php
$sql = "SELECT * FROM idx_item WHERE MATCH('about')";
$rows = Yii::$app->sphinx->createCommand($sql)->queryAll();

$rowSnippetSources = [];
foreach ($rows as $row) {
    $rowSnippetSources[] = file_get_contents('/path/to/index/files/' . $row['id'] . '.txt');
}

$snippets = Yii::$app->sphinx->createCommand($sql)->callSnippets('idx_item', $rowSnippetSources, 'about');
```

Вы можете упростить этот рабочий процесс, используя [[Yiisoft\Db\Sphinx\Query::snippetCallback]].
Это PHP колбек, который получает массив строк результата запроса в качестве аргумента и должен возвращать массив строк источника фрагмента в порядке, который соответствует одной из входящих строк.
Например:

```php
use Yiisoft\Db\Sphinx\Query;

$query = new Query();
$rows = $query->from('idx_item')
    ->match($_POST['search'])
    ->snippetCallback(function ($rows) {
        $result = [];
        foreach ($rows as $row) {
            $result[] = file_get_contents('/path/to/index/files/' . $row['id'] . '.txt');
        }
        return $result;
    })
    ->all();

foreach ($rows as $row) {
    echo $row['snippet'];
}
```

Если вы используете Active Record, вы можете создать фрагменты [[Yiisoft\Db\Sphinx\ActiveQuery::snippetByModel()]].
Этот метод извлекает источник фрагмента для каждой строки, вызывающий метод `getSnippetSource()` модели результата.
Все, что вам нужно сделать, это реализовать его в классе Active Record, чтобы он вернул правильное значение:

```php
use Yiisoft\Db\Sphinx\ActiveRecord;

class Article extends ActiveRecord
{
    public function getSnippetSource()
    {
        return file_get_contents('/path/to/source/files/' . $this->id . '.txt');;
    }
}

$articles = Article::find()->snippetByModel()->all();

foreach ($articles as $article) {
    echo $article->snippet;
}
```