Как правильно оформить поиск по сайту?

Пытаюсь организовать поиск на сайте по одной моделе (таблице) как кому нравится и вывод полученных данных через
ActiveDataProvider таким образом

public function actionSearch($query)
    {
        $search = Serial::find()->where(['or',['like', 'name_serial', $query],['like', 'description_serial', $query]])->limit(30);
        $searchDataprovider = new ActiveDataProvider([
            'query' => $search,
            'pagination' => [
                'pageSize' => 15,
            ],
        ]);
        return $this->render('search', [
            'searchDataprovider' => $searchDataprovider
        ]);
    }


если пишу Игра престолов все получаю и вот сразу же оформляю запрос в дебуге

SELECT * FROM `fl_serial` WHERE (`name_serial` LIKE '%Игра престолов%') OR (`description_serial` LIKE '%Игра престолов%') LIMIT 15


если же Елизавета I Лагерь X то ни чего не получаю вообще вот такой запрос в дебуге получаю не объясните как мне правильно оформить

SELECT * FROM `fl_serial` WHERE (`name_serial` LIKE '%Елизавета I%') OR (`description_serial` LIKE '%Елизавета I%') LIMIT 15

попробовал сделать так

public function actionSearch($query)
        {
        	
            $search = Serial::find()->where(['or',['like', 'name_serial', str_replace(' ','%',$query)],['like', 'description_serial', str_replace(' ','%',$query)]])->limit(30);
            $searchDataprovider = new ActiveDataProvider([
                'query' => $search,
                'pagination' => [
                    'pageSize' => 15,
                ],
            ]);
            return $this->render('search', [
                'searchDataprovider' => $searchDataprovider
            ]);
        }


получаю такой запрос

SELECT * FROM `fl_serial` WHERE (`name_serial` LIKE '%Елизавета//%I%') OR (`description_serial` LIKE '%Елизавета//%I%') LIMIT 15
  • Вопрос задан
  • 384 просмотра
Пригласить эксперта
Ответы на вопрос 2
xmoonlight
@xmoonlight
https://sitecoder.blogspot.com
Берите Fuzzy Search и не мучтесь.
Ответ написан
Insolita
@Insolita
Отчаянная домохозяйка
А что вы собственно ожидаете получить? www.yiiframework.com/doc-2.0/yii-db-queryinterface...

like: operand 1 should be a column or DB expression, and operand 2 be a string or an array representing the values that the column or DB expression should be like. For example, ['like', 'name', 'tester'] will generate name LIKE '%tester%'. When the value range is given as an array, multiple LIKE predicates will be generated and concatenated using AND. For example, ['like', 'name', ['test', 'sample']] will generate name LIKE '%test%' AND name LIKE '%sample%'. The method will properly quote the column name and escape special characters in the values. Sometimes, you may want to add the percentage characters to the matching value by yourself, you may supply a third operand false to do so. For example, ['like', 'name', '%tester', false] will generate name LIKE '%tester'.
or like: similar to the like operator except that OR is used to concatenate the LIKE predicates when operand 2 is an array.
not like: similar to the like operator except that LIKE is replaced with NOT LIKE in the generated condition.
or not like: similar to the not like operator except that OR is used to concatenate the NOT LIKE predicates.


если хотите чтоб по каждому слову из запроса искало - то предварительно разбивайте запрос по пробелам
public function actionSearch($query)
    {
        $subqueries = preg_split("/\s/u", $query, -1, PREG_SPLIT_NO_EMPTY);
        //Лучше потом отфильровать $subqueries убрав короткие слова или пошаманить с регуляркой что разбивало только если за пробелом слово больше n символов (чтоб Елизавета X так и осталась Елизавета X)
       // например так
       // $subqueries = preg_split("/\s(?=\w{2,})/u", $query, -1, PREG_SPLIT_NO_EMPTY)

        $search = Serial::find()->where(['or',['like', 'name_serial', $subqueries],['like', 'description_serial', $subqueries]]); 
        $searchDataprovider = new ActiveDataProvider([
            'query' => $search,
            'pagination' => [
                'pageSize' => 15,
            ],
        ]);
        return $this->render('search', [
            'searchDataprovider' => $searchDataprovider
        ]);
    }
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы