/**
  * fuzzy condition builder for nested documents
  *
  * @param $column
  * @param $value
  * @param float $boost
  * @param integer|string $fuzziness
  * @return array|bool
  */
 public static function nestedFuzzy($column, $value, $boost = null, $fuzziness = 'auto')
 {
     $matches = [];
     preg_match('#^(.*)\\.(\\w+)$#', $column, $matches);
     $cnt = count($matches);
     if (in_array($matches[$cnt - 1], self::$raw_cols)) {
         $matches[$cnt - 2] = $matches[$cnt - 2] . $matches[$cnt - 1];
         unset($matches[$cnt - 1]);
     }
     self::$is_nested_prepared = true;
     return ['nested' => ['path' => $matches[1], 'query' => self::fuzzy($column, $value, $boost, $fuzziness)]];
 }
 /**
  * @param array $query elastic search query:
  * [
  *    'query' => [],
  *    'aggs' => [],
  *    ...
  * ]
  * @param array $dataProviderOptions
  * [
  *    'pagination' => [],
  *    'sort' => [],
  *    ...
  * ]
  * @return ElasticActiveDataProvider
  */
 public function elasticSearch($query = [], $dataProviderOptions = [])
 {
     $this->owner->unsetAttributes();
     $filters = !empty($_REQUEST[get_class($this->owner)]) ? $_REQUEST[get_class($this->owner)] : [];
     $auto = [];
     $colSchema = $this->owner->tableSchema->columns;
     foreach ($filters as $col => $val) {
         if (!$val) {
             continue;
         }
         if (in_array($col, $this->owner->safeAttributeNames) && !property_exists($this->owner, $col)) {
             $val = $this->owner->{$col};
             if ($val !== null) {
                 /** @var CMysqlColumnSchema $desc */
                 $desc = isset($colSchema[$col]) ? $colSchema[$col] : null;
                 //integer, boolean, double, string
                 $colType = $desc ? $desc->type : 'string';
                 $temp = ElasticQueryHelper::compare($col, $val, $colType, true);
                 if ($temp) {
                     $auto[] = $temp;
                 }
             }
         } elseif (strchr($col, '.') !== false) {
             $temp = ElasticQueryHelper::nestedCompare($col, $val, 'string', false);
             if ($temp) {
                 $auto[] = $temp;
             }
         }
     }
     if (!empty($auto)) {
         $auto = ['bool' => ['must' => $auto]];
     }
     if (empty($query['query'])) {
         $qry = $auto;
     } else {
         $qry = CMap::mergeArray($auto, [$query['query']]);
         unset($query['query']);
     }
     if (!empty($qry)) {
         $options = CMap::mergeArray(['criteria' => CMap::mergeArray(['query' => ['bool' => ['must' => $qry]]], $query)], $dataProviderOptions);
     } else {
         $options = CMap::mergeArray(['criteria' => $query], $dataProviderOptions);
     }
     if (empty($options['criteria']['query']) && isset($options['criteria']['query'])) {
         unset($options['criteria']['query']);
     }
     return new ElasticActiveDataProvider(get_class($this->owner), $options);
 }