0

私はウェブサイト上の特定のタイプの投稿のためにPHP検索機能を構築してきました(この目的のために、mySQLは問題外であることを受け入れてください)。

一連の手順の後、タイトルと各投稿のタグを取得し、と呼ばれる変数に格納します$full

検索語は、という変数に含まれます$terms

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

どちらも小文字に変換されます。

$full次に、使用する際に類似した単語を探します$terms

これを試してみました。

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

それは機能しますが、私が必要とするほどではありません。

  • これは、タイトルとタグの類似した単語と一致しますが、スペースはまったく処理しません。タイトルとタグからスペースとカンマを削除してみましたが、役に立ちませんでした。
  • ユーザーが1つではなく2つのタグで構成されている誰かの名前を入力した場合、結果は見つかりません。
  • 複数の単語はもちろん、複数の用語を処理することはできません。どちらも私が望んでいることです。

役立つ場合は、ここに完全なスクリプトがあります

$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

実際の検索エンジンがこれを行う方法は、逆索引を作成することです。つまり、最も単純な形式で、各単語から、その単語が何回含まれているドキュメントのセットまでのルックアップ テーブルです。(ここで、ドキュメントは単に検索対象のテキストを意味します)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 に答える
0

あなたがそれを達成できるいくつかの方法があります。私はいくつかを試して提供します:

STRPOS

これは赤と一致してから停止しますが、正確ではない単語にも一致します。たとえば、車もカードと一致します.

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

3 番目のアプローチは、正規表現と preg_quote を使用することですが、strpos と同じ問題が発生する可能性が高くなります。

それが役立つことを願っています

于 2011-12-08T16:37:41.647 に答える