Как искать случайные слова из фразы, используя PHP? - PullRequest
0 голосов
/ 02 мая 2011

Мое оригинальное Pname в таблице 'english' - "Цифровая кружка Санта-Моники". Если пользователи пытаются выполнить поиск с помощью "Цифровой кружки", продукт не возвращается с pname, содержащим цифровую кружку.

используюэтот запрос:

select * 
from english 
where((pname like '%$val%' 
       or  desp1 like '%$search%' 
       or pid like '%$search%' $key_value) 
      and warehouse=0 and cid !=49) 
group by pid;

Ответы [ 5 ]

2 голосов
/ 02 мая 2011

используйте pname like '%".implode('%', explode(' ', $val))."%' вместо pname like '%$val%'

В этом случае порядок будет иметь значение.Значит Digital Mug даст вам результат, а MUG Digital - нет.

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

Либо то, что советовал C Man (разделить поисковую фразу и поиск по каждому слову), либо полнотекстовый поиск.


Для метода "расщепления слов" я бы посоветовал:

  • использовать регулярные выражения для разбиения, что-то вродеpreg_match_all('#[a-zA-Z0-9]+#', $text, $words);Вам не нужно искать такие символы, как "$", не так ли?
  • написать функцию, которая будет генерировать для вас предложение where.

Функция для генерации where Предложение может выглядеть следующим образом:

function generateFilter(array $fields, array $words) {
    // prepare $word for putting into SQL statement
    foreach ( $words as &$word ) {
        // ensure that wildcard characters are used as regular characters
        $word = str_replace('%', '\\%', $word);
        $word = str_replace('_', '\\_', $word);
        // prevent SQL injections
        $word = mysql_real_escape_string($word);
    }
    unset($word);
    // generate filter
    $filter = array();
    foreach ( $words as $word ) {
        $wordFilter = array();
        foreach ( $fields as $field ) {
            $wordFilter[] = "{$field} like '%$word%'";
        }
        $filter[] = implode(' or ', $wordFilter);
    }
    $filter = '(' . implode(') and (', $filter) . ')';
    return $filter;
}
$filter = generateFilter(
    array('name', 'surname', 'address'),
    array('john', 'doe')
);
echo $filter;

Результат:

(name like '%john%' or surname like '%john%' or address like '%john%') and
(name like '%doe%' or surname like '%doe%' or address like '%doe%')

Если вы используете подготовленные операторы (что настоятельно рекомендуется), эта функция будет немного более сложной, так как в результатестрока будет иметь заполнители для переменных, в то время как $ words будет помещен в некоторый массив переменных, которые должны быть связаны с подготовленным оператором.


Метод «Разделение слов» работает для небольших строк и небольших объемов данных.,Если у вас есть большие объемы данных и / или большие строки, рассмотрите возможность использования полнотекстового поиска.Он не требует разделения поисковой фразы, хотя имеет некоторые ограничения - ему нужен полнотекстовый индекс по столбцам, которые используются для поиска (IIRC, вы можете создать индекс по нескольким столбцам и затем использовать полнотекстовый поиск по всем индексированным столбцам одновременно,т. е. вам не нужно искать каждый столбец отдельно), он имеет минимальную длину ключевого слова и может давать не строгие результаты, например, иногда в результате могут появляться только 3 из 5 ключевых слов.Тем не менее, это дает релевантность каждого результата - результаты, которые ближе к условиям поиска, будут иметь более высокую релевантность.Это полезно для сортировки результатов по релевантности.

Хотя создание индекса может показаться вам «дополнительной работой», это позволит СУБД выполнять поиск быстрее, чем без индекса.

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

Используйте полнотекстовый поиск для этого

Эта вещь не работает как The Digital Santa Monica Mug при поиске как Digital Mug будет восприниматься как '%Digital Mug%', который пытается найти значение, имеющее Digital Mug, имеющее слова переди после.

Eg : THE Digital Mug Paradise

Такой текст будет сопоставлен.

Поэтому попробуйте MYSQL ПОЛНЫЙ ТЕКСТ ПОИСК для этого

ПОЛНЫЙ ТЕКСТ ПОИСК

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

Вы можете разделить входное значение на два разных слова.Чтобы сделать это, выполните

$term_array = explode(" ", $val);

. Теперь $ term_array будет хранить оба слова по отдельности, и вы можете выполнять запросы к словам по отдельности.Например, вы можете выполнить запрос дважды и выполнить один и тот же запрос для отдельных слов.Тем не менее, выполнение этого приведет к дублированию (и, вероятно, некоторые ненужные результаты).Возможно, вы могли бы подумать о каком-то запросе, используя два разделенных слова, которые могли бы дать лучшие результаты.

0 голосов
/ 02 мая 2011

Для построения запроса:

$split = explode(" ", $val);
$qry_pname = "pname LIKE '%".implode("%' or pname LIKE '%", $split)."'%";

$qry = "
SELECT * 
   FROM english 
WHERE( $qry_pname
       or  desp1 like '%$search%' 
       or pid like '%$search%' $key_value) 
      and warehouse=0 and cid !=49) 
group by pid;
";
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...