0

我一直在为网站上某些类型的帖子构建一个 PHP 搜索工具(为此,请接受 mySQL 是不可能的)。

经过一系列程序,我们得到了每个帖子的标题和标签,并将它们存储在一个名为$full.

搜索词位于一个名为的变量中$terms

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

两者都转换为小写。

$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>';

     }
    }


}

价值

$terms 可能包含用户为搜索输入的一些值,例如“红色汽车”;

$full 包含帖子标题和标签,所以它可能会说。“红色的 vaxhaul 不是很好,车辆,汽车,可怕,丑陋”

所以应该在这种情况下找到。

4

2 回答 2

0

有几种方法可以实现,我会尝试提供一些:

STRPOS

这将匹配红色然后停止,但它也会匹配非精确的单词,例如 car 也会匹配卡片等。

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

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

使用数组交集

//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 有相同的问题

希望有帮助

于 2011-12-08T16:37:41.647 回答
0

真正的搜索引擎这样做的方式是建立一个倒排索引,即最简单的形式是一个查找表,从每个单词到包含该单词的文档集以及包含多少次。(其中文档仅表示正在搜索的文本)在 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 中也有该信息。这种方法非常快,但您必须提前构建倒排索引,但它比实际搜索要快得多。

于 2011-12-08T17:49:17.323 回答