Php / MySql Страница «Расширенный поиск» - PullRequest
8 голосов
/ 02 января 2009

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

Найти: Со всеми словами, С точная фраза, по крайней мере, с одним из слова, без слов

Я могу позаботиться о «Точной фразе»:

SELECT * FROM myTable WHERE field='$keyword';

«По крайней мере, одно из слов»:

SELECT * FROM myTable WHERE field LIKE '%$keyword%';//Let me know if this is the wrong approach

Но это «С хотя бы одним словом» и «Без слов», на которых я застрял.

Есть предложения о том, как реализовать эти два?

Редактировать: Относительно 'По крайней мере, одного слова' было бы неправильно использовать explode (), чтобы разбить ключевые слова на слова, и запустить цикл для добавления

(field='$keywords') OR ($field='$keywords) (OR)....

Поскольку в запросе также есть некоторые другие операторы AND / OR, и я не знаю, какое максимальное количество предложений может быть.

Ответы [ 5 ]

13 голосов
/ 02 января 2009

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

Edit:

Запрошенный пример, основанный на ваших запрошенных условиях («Это всего одно поле, и они могут выбрать любой из 4 вариантов (т.е. 1 слово, точные слова, не менее 1 слова, без термина).)

Я предполагаю, что вы используете php на основе вашего первоначального сообщения

<?php
$choice = $_POST['choice'];
$query = $_POST['query'];

if ($choice == "oneWord") {
    //Not 100% sure what you mean by one word but this is the simplest form
    //This assumes $query = a single word
    $result = mysql_query("SELECT * FROM table WHERE MATCH (field) AGAINST ('{$query}' IN BOOLEAN MODE)");
} elseif ($choice == "exactWords") {
    $result = mysql_query("SELECT * FROM table WHERE MATCH (field) AGAINST ('\"{$query}\"' IN BOOLEAN MODE)");
} elseif ($choice == "atLeastOneWord") {
    //The default with no operators if given multiple words will return rows that contains at least one of the words
    $result = mysql_query("SELECT * FROM table WHERE MATCH (field) AGAINST ('{$query}' IN BOOLEAN MODE)");
} elseif ($choice == "withoutTheTerm") {
    $result = mysql_query("SELECT * FROM table WHERE MATCH (field) AGAINST ('-{$query}' IN BOOLEAN MODE)");
}
?>

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

2 голосов
/ 02 января 2009

Я не уверен, что вы могли бы легко сделать эти параметры поиска наивным способом, как два других.

Было бы целесообразно внедрить лучшую поисковую систему, если вам необходимо поддерживать эти сценарии. Простой способ, который мог бы вам помочь, - это что-то вроде этого:

Когда элемент добавляется в базу данных, он разделяется на отдельные слова. На этом этапе «общие» слова (the, a и т. Д.) Удаляются (вероятно, на основе таблицы common_words). Остальные слова добавляются в таблицу слов, если их еще нет. Затем создается ссылка между записью слова и записью элемента.

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

2 голосов
/ 02 января 2009

Вы можете использовать

Как минимум с одним из слов

SELECT * FROM myTable WHERE field LIKE '%$keyword%' 
or field LIKE '%$keyword2%' 
or field LIKE '%$keyword3%';

Без слова

SELECT * FROM myTable WHERE field NOT LIKE '%$keyword%';
1 голос
/ 02 января 2009

Поиск, как известно, трудно сделать хорошо.

Вам следует рассмотреть возможность использования сторонней поисковой системы, использующей что-то вроде Lucene или Sphider .

0 голосов
/ 02 января 2009

Жираф и Re0sless поставили 2 хороших ответа.

примечания: «SELECT *» - отстой ... выбирайте только те столбцы, которые вам нужны. Re0sless ставит «ИЛИ» между ключевыми словами. - вы должны исключить общие слова ("", "я", "я", "и" и т. д.) - mysql имеет 8-килобайтное ограничение на размер запроса, поэтому для действительно длинных SELECTS вы должны разделить его на отдельные запросы. - попытаться исключить повторяющиеся ключевые слова (если я ищу «вы знаете, что вам это нравится», SELECT должен в основном искать «вы» только один раз и исключать общие слова как «это»)

Также попробуйте использовать «LIKE» и «MATCH LIKE» (см. Справочную страницу mysql), это может творить чудеса при «нечетких» поисках

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