Понадобилось мне искать строку сразу в нескольких полях. Думал-думал и решил использовать полнотекстовый поиск MySQL. Довольно простая, но хитрая штука.
При создании таблицы в бд, надо добавить строку FULLTEXT (title,body)
(где title,body — поля для поиска):
CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200),
body TEXT,
FULLTEXT (title,body)
) ENGINE=InnoDB;
Если же таблица уже создана, то выполняем запрос в MySQL:
CREATE FULLTEXT INDEX title_body ON articles(title,body)
Теперь для поиска по полям можем использовать вот такой MySQL запрос:
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('текст');
Но в данном случае будет поиск по полному соответствию фразы «текст» в полях title и body. Т.е. найти «текс», а получить все строки с «текст» не получится.
Чтобы искать часть строки, нужно обернуть искомую строку в звездочки * и добавить IN BOOLEAN MODE:
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('*текст*' IN BOOLEAN MODE);
А что с OctoberCMS?
Всё очень просто, используем чистый запрос к MySQL:
$article = Article::whereRow("MATCH (title,body) AGAINST ('*текст*' IN BOOLEAN MODE")->get();
Важный момент. В запросе обязательно нужно использовать все поля, которые указали для полнотекстового поиска при создании таблицы. Т.е. нельзя использовать конструкцию MATCH (title)
, нужно обязательно использовать MATCH (title,body)
.