Изменить функцию под SQL запрос

D
На сайте с 28.06.2008
Offline
1108
829

Есть функция

function getSearch($names)
{
$sql = array();

if(!empty($names))
{
foreach($names as $name)
{
$sql[] = "name LIKE ".$this->_db->quote('%'.$name.'%')."";
}
}

if(!empty($sql))
{
$this->_db->setQuery("SELECT id, name, description, price, url, picture AS image FROM #__price2 WHERE price > 1 AND (".implode(' OR ', $sql).") ORDER BY price DESC LIMIT 25");
return $this->_db->loadObjectList();
}
}

которая генерирует подобные запросы:

SELECT id, name, description, price, url, picture AS image
FROM x4q7_price2
WHERE price > 1 AND (name LIKE '%Свитер%')
ORDER BY price DESC LIMIT 25;

Таблица большая и запрос иногда выполняется более 1 сек. Я добавил FULLTEXT индекс и проверил запрос вида

SELECT id, name, description, price, url, picture AS image
FROM x4q7_price2
WHERE price > 1 AND MATCH(name) AGAINST('Свитер')
ORDER BY price DESC LIMIT 25

теперь он выполняется 0,005 сек.

Помогите теперь изменить пхп код под полнотекстовый поиск.

edogs software
На сайте с 15.12.2005
Offline
775
#1

function getSearch($names)
{
$sql = array();

if(!empty($names))
{
foreach($names as $name)
{
$sql[] = "+".$this->_db->quote($name)."";
}
}

if(!empty($sql))
{
$this->_db->setQuery("SELECT id, name, description, price, url, picture AS image FROM #__price2 WHERE price > 1
AND ( match(name) against '".implode(' ', $sql)."' in boolean mode) ORDER BY price DESC LIMIT 25");
return $this->_db->loadObjectList();
}
}

Примерно так.

Почему boolean mode ? Потому что Вам нужен точный поиск видимо, а не что там мускулу в голову взбредет.

Так же неплохо бы в my.cnf проставить

ft_stopword_file = ""

ft_min_word_len = 1

Первое что бы искало по любым словам, без исключений в виде стопслов.

Второе что бы длина слов была от 1 символа (по умолчанию 3, но если иногда ищите по "и" то придется ставить 1).

Кроме того, учтите, что фултекст ищет слова.

Лайком Вы "мойсвитер" по слову "свитер" найдете и "свитера" тоже, а фултекстом уже нет.

Однако можно найти "свитера" по слову "свитер" если запрос составлять не как +свитер, а как +свитер*, но "мойсвитер" не найдете все равно.

$sql[] = "+".$this->_db->quote($name)."*";

Кроме того если в таблица в innodb, то о +слово* забудьте, это innodb не умеет, умеет myisam. Фултекст в иннодб хоть и впилили наконец-то, но он там еще не дотягивает.

p.s.: Можете посмотреть на sphinx. Как фултекст поиск он во многих вещах лучше мускула, однако жрет память дай боже и в булевом поиске особых преимуществ не имеет.

Разработка крупных и средних проектов. Можно с криптой. Разумные цены. Хорошее качество. Адекватный подход. Продаем lenovo legion в спб, дешевле магазинов, новые, запечатанные. Есть разные. skype: edogssoft
C
На сайте с 04.02.2005
Offline
291
#2

Как то вы пугаете :(

уже ответили.....

D
На сайте с 28.06.2008
Offline
1108
#3

edogs, SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''+'Свитер'' in boolean mode) ORDER BY price DESC LIMIT 25' at line 1

---------- Добавлено 26.09.2017 в 17:35 ----------

Chukcha, SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'MATCH(name) AGAINST('%Свитер%')) ORDER BY price DESC LIMIT 25' at line 1

edogs software
На сайте с 15.12.2005
Offline
775
#4
Dram:
edogs, SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''+'Свитер'' in boolean mode) ORDER BY price DESC LIMIT 25' at line 1

А что у Вас функция db->quote делает? Добавляет кавычки вокруг кроме всего прочего?

В общем запрос должен получится вида match (name) against ('+Свитер +шерсть' in boolean mode)

Проще всего вероятно так

В цикле $sql[] = "+".$name.""

а дальше не AND ( match(name) against '".implode(' ', $sql)."' in boolean mode) ORDER BY

А нечто вроде AND ( match(name) against ( ".$this->_db->quote(implode(' ', $sql))." in boolean mode) ) ORDER BY

---------- Добавлено 26.09.2017 в 18:29 ----------

Chukcha:
Как то вы пугаете :(
уже ответили.....
Через час? Да вроде не так что бы скорость:)
D
На сайте с 28.06.2008
Offline
1108
#5

Спасибо, вроде работает :))

C
На сайте с 04.02.2005
Offline
291
#6
edogs:
Через час? Да вроде не так что бы скорость

та пока писал, отвлекли, продолжил

Упс.. а там более продвинутый ответ

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий