PHP поиск по ключевым словам - PullRequest
0 голосов
/ 08 декабря 2011

Я строю средство поиска PHP для определенных типов сообщений на веб-сайте (для этого, пожалуйста, примите, что о MySQL не может быть и речи).

После ряда процедур мы получаемtitle и теги для каждого сообщения и сохраните их в переменной с именем $full.

. Условия поиска находятся в переменной с именем $terms

$full = $title . ' ' . $tago[$result->ID];

Оба преобразуются в нижниеcase.

Затем мы хотим найти похожие слова в $full, используя $terms

Я попробовал это.

$final = strpos($full,$terms);

Это работает, но не совсем какну, мне это нужно.

  • Это будет соответствовать аналогичным словам из заголовка и тегов, но не будет иметь дело с пробелами вообще.Я попытался удалить пробелы и запятую из заголовков и тегов, но безрезультатно.
  • Если пользователь вводит кому-то имя, состоящее из двух тегов, а не одного, он не найдет никаких результатов.
  • Он не может обрабатывать более одного слова, не говоря уже о нескольких терминах, оба из которых я хочу, чтобы он делал.

Вот полный сценарий, если он поможет

$proto = $_GET['p'];
$terms = $_GET['s'];

$terms = strtolower($terms);
$terms = str_replace(' ', '', $terms);

$ids = array();

if($proto == 'inline') {

    $search = get_posts('post_type=post&post_status=publish');

    foreach($search as $result) {

        $title = get_the_title($result);

        $tags = wp_get_post_tags( $result->ID);

        foreach($tags as $tag){ $tago[$result->ID].= $tag->name;}

        $full = $title . ' ' . $tago[$result->ID];
        $full = strtolower($full);
        $final = strpos($full,$terms);


        if($final != false){ 

            $ids[] = $result->ID;

         }

    }
    if ($ids[0] == '') { 
        echo '<div align="center" style="text-align:center; color:#FFF;">No Results Found</div>';
    return false; } else {
    $args = array( 'post__in' => $ids );

    $srs = get_posts($args);

    foreach($srs as $sr) { 

    echo '<a href="'.$sr->post_slug.'"><img src=""/><b>'.$sr->post_title.'</b>'. $tago[$result->ID].'<span>'.date('dS M Y', strtotime($sr->post_date)).'</span></a>';

     }
    }


}

VALUES

$ term могут содержать некоторые значения, вводимые пользователем для поиска, скажем, 'red car';

$ full содержит заголовок сообщения и теги, чтобы онможно сказать.«Красный vaxhaul не очень хороший, автомобиль, машина, ужасный, уродливый»

Так что это должно быть найдено в этом случае.

Ответы [ 2 ]

0 голосов
/ 08 декабря 2011

Способ, с помощью которого настоящая поисковая система могла бы сделать это, состоит в том, чтобы создать инвертированный индекс, то есть в его простейшей форме таблицу поиска по каждому слову в наборе документов, в которых есть это слово, и сколько раз.(где документы просто означают текст, по которому выполняется поиск) Довольно просто сделать это в php:

foreach($documents as $docIndex => $documentText) {
    //remove all types of punctuation and other characters here
    $documentText = str_replace(array(',','.','?','!'),"",$documentText);
    $words = explode(" ",$documentText);
    foreach($words as $word) $invertedIndex[$word][$docIndex]++;
}

после запуска, мы создали инвертированный индекс.Теперь, чтобы использовать его на вашем примере, входящий запрос - «красная машина».разбейте их на части и найдите $ invertedIndex ['red'] и $ invertedIndex ['car'], каждый из которых будет возвращать массивы, в которых есть все документы с этими словами и сколько раз.Чтобы получить документы с обоими, используйте array_intersect, чтобы получить документы с любым из них, используя array_merge для ключей этих массивов:

foreach($keywords as $count => $keyword) {
    if($count == 0) $validDocs = keys($invertedIndex[$keyword]);
    $validDocs = array_intersect(keys($invertedIndex[$keyword]),$validDocs);
}

Теперь индекс документа для каждого документа со всеми ключевыми словами будет в $ validDocs, и если вы хотитечтобы ранжировать их по тому, сколько раз слова встречались в тексте, у вас тоже есть эта информация в $ invertedIndex.Этот метод очень быстрый, но вам нужно заранее построить инвертированный индекс, но он будет намного быстрее, чем на самом деле.

0 голосов
/ 08 декабря 2011

Есть несколько способов добиться этого, я постараюсь предоставить несколько:

StrPos

Это будет соответствовать красному цвету и затем остановится, но это также будет соответствовать не точным словам, например, автомобиль также будет соответствовать карточкам и т. Д.

$words = explode(' ', $terms);

foreach ($words as $word) 
{
    if (false !== strpos()) {
        $ids[] = $result->ID;
    }
}

Использование массива Intersec

//create an array of searched terms
$words = explode(' ', $terms);

//remove non letter numbers
$fullClean = preg_replace('/[^a-z\d\s]/', '', $full);

//Create an array of words
$criteria = explode(' ', $fullClean);

//find if any elements of $words exist in $criteria
if (count(array_intersect($words, $criteria))) {
    $ids[] = $result->ID;
}

Третий подход может заключаться в использовании регулярных выражений и preg_quote, но, скорее всего, он будет иметь ту же проблему, что и strpos

Надеюсь, это поможет

...