Поиск в базе данных с использованием `LIKE` и` MATCH AGAINST` в MySQL - PullRequest
1 голос
/ 26 апреля 2019

В моей базе данных есть таблица с именем pro_search, куда я перевел метаинформацию для различных продуктов на разные языки.

Моя структура таблицы выглядит так: id pro_id en de es fr it nl pl pt, где pro_id - это идентификаторпродукт и двухбуквенный код в других столбцах представляют язык перевода метаданных этого продукта.

Я запустил следующий код для создания индексов FULLTEXT в моей базе данных:

ALTER TABLE pro_search ADD FULLTEXT INDEX `FullText` (`en` ASC, `de` ASC, `es` ASC, `fr` ASC, `it` ASC, `nl` ASC, `pl` ASC, `pt` ASC);
ALTER TABLE pro_search ADD FULLTEXT INDEX `enFullText` (`en` ASC);
ALTER TABLE pro_search ADD FULLTEXT INDEX `deFullText` (`de` ASC);
ALTER TABLE pro_search ADD FULLTEXT INDEX `esFullText` (`es` ASC);
ALTER TABLE pro_search ADD FULLTEXT INDEX `frFullText` (`fr` ASC);
ALTER TABLE pro_search ADD FULLTEXT INDEX `itFullText` (`it` ASC);
ALTER TABLE pro_search ADD FULLTEXT INDEX `nlFullText` (`nl` ASC);
ALTER TABLE pro_search ADD FULLTEXT INDEX `plFullText` (`pl` ASC);
ALTER TABLE pro_search ADD FULLTEXT INDEX `ptFullText` (`pt` ASC);

enter image description here

Затем я попытался сделать несколько тестов, чтобы увидеть, какие результаты я получу:

$lang = 'en';
$term = 'this is a test';

$params = [$term];
$sql = "SELECT * FROM pro_search WHERE $lang=?;";
$stmt = DB::run($sql,$params);
$count = $stmt->rowCount();
echo $count.'<br />';
// returns '1' so there is definitely a match

$params = ['%'.$term.'%'];
$sql = "SELECT * FROM pro_search WHERE $lang LIKE '?';";
$stmt = DB::run($sql,$params);
$count = $stmt->rowCount();
echo $count.'<br />';
// returns '0'

$params = [$term];
$sql = "SELECT * FROM pro_search WHERE MATCH ($lang) AGAINST ('?');";
$stmt = DB::run($sql,$params);
$count = $stmt->rowCount();
echo $count.'<br />';
// returns '0'

$params = [$term];
$sql = "SELECT * FROM pro_search WHERE MATCH ($lang) AGAINST ('?' IN NATURAL LANGUAGE MODE);";
$stmt = DB::run($sql,$params);
$count = $stmt->rowCount();
echo $count.'<br />';
// returns '0'

$params = [$term];
$sql = "SELECT * FROM pro_search WHERE MATCH ($lang) AGAINST ('?' WITH QUERY EXPANSION);";
$stmt = DB::run($sql,$params);
$count = $stmt->rowCount();
echo $count.'<br />';
// returns '0'

$params = [$term];
$sql = "SELECT * FROM pro_search WHERE MATCH ($lang) AGAINST ('?' IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION);";
$stmt = DB::run($sql,$params);
$count = $stmt->rowCount();
echo $count.'<br />';
// returns '0'

Как вы можете видеть первый точныйзапрос возвращает результат, и если я делаю запрос непосредственно в phpMyAdmin из SELECT * FROM pro_search WHERE en LIKE '%test%', я получаю всего 7 результатов, но ни один во втором запросе здесь, в моем файле php, который точно такой же.

Я что-то упустилВот?Я думал, что все они должны возвращать по крайней мере один результат, если не больше.

Редактировать

Вот мой код создания для моей таблицы в том виде, в каком он есть на всякий случай:

CREATE TABLE `pro_search` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `pro_id` int(11) NOT NULL,
 `en` varchar(255) DEFAULT NULL,
 `de` varchar(255) DEFAULT NULL,
 `es` varchar(255) DEFAULT NULL,
 `fr` varchar(255) DEFAULT NULL,
 `it` varchar(255) DEFAULT NULL,
 `nl` varchar(255) DEFAULT NULL,
 `pl` varchar(255) DEFAULT NULL,
 `pt` varchar(255) DEFAULT NULL,
 PRIMARY KEY (`id`),
 FULLTEXT KEY `FullText` (`en`,`de`,`es`,`fr`,`it`,`nl`,`pl`,`pt`),
 FULLTEXT KEY `enFullText` (`en`),
 FULLTEXT KEY `deFullText` (`de`),
 FULLTEXT KEY `esFullText` (`es`),
 FULLTEXT KEY `frFullText` (`fr`),
 FULLTEXT KEY `itFullText` (`it`),
 FULLTEXT KEY `nlFullText` (`nl`),
 FULLTEXT KEY `plFullText` (`pl`),
 FULLTEXT KEY `ptFullText` (`pt`)
) ENGINE=MyISAM AUTO_INCREMENT=1597 DEFAULT CHARSET=latin1

Кроме того, как люди будут рекомендовать поиск на нескольких языках?Я настроил его таким образом, чтобы мета продукта переводилась, но у нас нет переводчика, поэтому некоторые из них прямо из Google translate с несколькими изменениями здесь и там.Однако, если мне это удастся, я могу попытаться создать индекс непосредственно из таблицы продуктов, которая включает название продукта, описание и мета.

Как мне кажется, у меня есть два варианта:

  1. Хранить переводы продуктов и искать их, или
  2. Перевести поисковый запрос и поиск на английском языке

В любом случае мы, вероятно, будем иметь дело с плохими переводами Google.

Ответы [ 3 ]

1 голос
/ 29 апреля 2019

Попробуйте удалить ' вокруг вашего?

  $params = ['%'.$term.'%'];
  $sql = "SELECT * FROM pro_search WHERE $lang LIKE ?;";
  $stmt = DB::run($sql,$params);
  $count = $stmt->rowCount();
  echo $count.'<br />';

В первом утверждении вы добавляете строковый параметр без кавычек: $lang=?.Это будет означать, что вам не нужны одинарные кавычки вокруг ? для других операторов;

1 голос
/ 02 мая 2019

Только первый запрос не имеет кавычек.

Таким образом, DB :: run добавляет кавычки.

Удаляет кавычки из всех запросов MATCH ... AGAINST.

Thisкак они должны работать все.

РЕДАКТИРОВАТЬ: попробуйте это

$params = [$term];
$sql = "SELECT * FROM pro_search WHERE MATCH ($lang) AGAINST (?);";
$stmt = DB::run($sql,$params);
$count = $stmt->rowCount();
echo $count.'<br />';
0 голосов
/ 29 апреля 2019

Я предполагаю, DB::run($sql,$params); добавляет кавычки в строку? Если это так, он создает

WHERE en LIKE '"stuff"'

Удалить ваши цитаты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...