/** * 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); }