Построение многопараметрического поискового запроса MySQL - PullRequest
3 голосов
/ 21 сентября 2009

Я пытаюсь создать поисковый запрос в MySQL, используя несколько аргументов, и я не совсем понимаю, как это сделать.

Я получаю аргументы поиска из формы и использую их для динамического построения моего запроса.

Вот некоторая справочная информация:

У меня есть база данных MySQL, содержащая информацию о задании. Есть четыре столбца, которые я хочу найти:

  1. Должность
  2. Тип работы
  3. Описание работы
  4. Место работы

Должность: Это заголовок должности на 1-5 слов. Может отличаться в зависимости от способа ввода

Тип работы: Это трехбуквенный код для типа работы.

Описание работы: Это краткое описание работы и обязанностей

Расположение: Это город или поселок

Пользователь будет искать, используя форму поиска. Форма поиска состоит из трех частей. Два текстовых поля: «ключевые слова» и «местоположение»; и выпадающий список с списком около 20 типов работ. Это позволит им выбирать между тремя буквенными кодами для списков вакансий.

Я бы хотел взять информацию из этих трех разделов формы и использовать ее для поиска в моей базе данных и для получения наиболее точных записей. Я пробовал несколько итераций своего запроса, и он либо возвращает много несвязанных записей, либо не возвращает достаточно связанных. Мне также не удалось учесть, что пользователь намеренно оставил части формы пустыми.

Мой текущий запрос выглядит примерно так:

select * FROM my_jobs_table
WHERE category = 'User specified job type'
OR job_title LIKE 'User specified Job keyword'
OR job_description LIKE 'User specified Job keyword '
OR location LIKE "% User Specified Job Location%"

Это просто не работает для меня. Есть предложения?

Ответы [ 3 ]

3 голосов
/ 21 сентября 2009

Различные решения "LIKE '%keyword%'" не имеют хорошей производительности. Я предлагаю вам использовать FULLTEXT INDEX вместо этого (при условии, что ваша таблица использует механизм хранения MyISAM).

CREATE FULLTEXT INDEX jobsearch_idx ON my_jobs_table (job_title, job_description, location);

Затем вы можете искать, используя оператор MATCH():

SELECT * FROM my_jobs_table
WHERE MATCH(job_title, job_description, location) AGAINST( ? );

Замените указанные пользователем ключевые слова, где у меня есть "?" выше. Кстати, я предполагаю, что разумный дизайн позволил бы найти ключевые слова местоположения, если они встречаются в заголовке или описании. Поэтому в вашем приложении объедините ключевые слова с выбором местоположения (через пробел) и используйте его для параметра запроса.

Я специально исключил category из этого примера, потому что я предполагаю, что вы хотите, чтобы имена категорий точно совпадали. Поэтому добавьте его с помощью оператора AND, например:

SELECT * FROM my_jobs_table
WHERE category = ?
  AND MATCH(job_title, job_description, location) AGAINST( ? );

Замените два пользовательских варианта (категорию и ключевые слова) на два заполнителя "?", указанных выше. Используйте параметры запроса, а не переменную интерполяцию.

Конечно, существует множество других опций для полнотекстовых индексов MySQL. Вы можете использовать модификатор поиска "IN BOOLEAN MODE", например. Я не буду описывать их полностью здесь, вы должны прочитать разделы руководства, чтобы узнать больше об этом.

Справочное руководство по MySQL 5.1: функции полнотекстового поиска .

Что касается обработки случаев, когда пользователи оставляют поля формы пустыми, это другая проблема, отдельная от поиска в базе данных. Вы должны решить эту проблему в Javascript или в коде приложения, либо установив значение по умолчанию, если пользователь не дает его, либо вернув их в форму и сообщив, что они не могут продолжить работу, не указав значение для обязательных полей.

1 голос
/ 21 сентября 2009

Если вы используете LIKE, вы должны поместить% на обоих концах строки. % является символом подстановки:

SELECT * FROM my_jobs_table
WHERE category = 'User specified job type'
OR job_title LIKE '%keyword%'
OR job_description LIKE '%keyword%'
OR location LIKE '%location%'

Вы действительно должны использовать параметризованные запросы. (См. здесь для некоторых примеров.) По крайней мере, убедитесь, что вы избегаете предоставленных пользователем частей запроса.

0 голосов
/ 21 сентября 2009

То, что я делаю в этой ситуации, - это создание базового запроса без JOIN или WHERE. Затем я перебираю значения запроса и строю свой запрос. Примерно так:

$q="SELECT * FROM my_jobs_table";

foreach($post as $key=>$value) { //assuming you cleaned & validated the $_POST into $post
  switch($key)
     case 'category':
       $wheres[]="$key ='$value'";
       break;
     case 'job_title':
     case 'job_description':
     case 'location':
       $wheres[]="$key LIKE '%{$value}%'";
       break;
  }
}
$where='WHERE ' . implode(' AND ', $wheres); //put on a condition to check for empty($wheres)
$q .= $where;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...