我一直在为网站上某些类型的帖子构建PHP搜索工具(为此目的,请接受mySQL是不可能的)。
经过一系列的过程后,我们得到了标题和每篇文章的标签,并将它们存储在一个名为$full
的变量中。
搜索项位于名为$terms
$full = $title . ' ' . $tago[$result->ID];
都转换为小写
然后我们想要使用$terms
$full
中查找类似的单词我试过了。
$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可能包含用户为搜索输入的一些值,例如,'red car';
$full包含文章标题和标签,所以它可能会说。"红色的搬运车不太好,车,车,可怕,丑陋"
应该在这里找到
有几种方法可以实现,我将尝试提供几种方法:
大小写敏感
这将匹配红色然后停止,但也会匹配非精确单词,例如car也会匹配cards等。
$words = explode(' ', $terms);
foreach ($words as $word)
{
if (false !== strpos()) {
$ids[] = $result->ID;
}
}
Using Array 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
相同的问题。希望有帮助
真正的搜索引擎会这样做的方式是建立一个反向索引,也就是说,以最简单的形式,从每个单词到包含该单词的文档集及其出现次数的查找表。(这里文档只是指正在搜索的文本)在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中获得该信息。这个方法非常快但是你需要提前建立倒排索引但是它会比实际搜索快得多