0

なぜこれがどこにも見つからないのかわかりません。これはかなり一般的な要求だと思います。PHP で検索エンジンを作成して、ユーザーが入力したキーワードの販売リストの MySQL データベースを検索しています。

テーブルにはいくつかの列がありますが、検索する必要があるのは 2 つだけです。これらは、file_Title および file_Desc という名前です。クラシファイド広告のようなものと考えてください。アイテムのタイトルと説明。

たとえば、ユーザーは「John Deere Lawn Tractor」を検索します。私が実現したいのは、これら 4 つの単語すべてがリストの一番上に表示される広告です。次に、3つしかない結果など。

http://www.roscripts.com/PHP_search_engine-119.htmlの非常に優れた Web ページを読みました。

その著者の例から、私は以下のコードを持っています:

<?php
    $search = 'John Deere Lawn Tractors';
    $keywords = split(' ', $search);

    $sql = "SELECT DISTINCT COUNT(*) As relevance, id, file_Title, file_Desc FROM Listings WHERE (";

    foreach ($keywords as $keyword) {
        echo 'Keyword is ' . $keyword . '<br />';
        $sql .= "(file_Title LIKE '%$keyword%' OR file_Desc LIKE '%$keyword%') OR ";
    }
    $sql=substr($sql,0,(strLen($sql)-3));//this will eat the last OR

    $sql .= ") GROUP BY id ORDER BY relevance DESC";
    echo 'SQL is ' . $sql;  

    $query = mysql_query($sql) or die(mysql_error());
    $Count = mysql_num_rows($query);
    if($Count != 0) {
                echo '<br />' . $Count . ' RESULTS FOUND';
        while ($row_sql = mysql_fetch_assoc($query)) {//echo out the results
            echo '<h3>'.$row_sql['file_Title'].'</h3><br /><p>'.$row_sql['file_Desc'].'</p>';
        }
    } else  {
        echo "No results to display";
    }

?>

出力される SQL 文字列は次のとおりです。

 SELECT DISTINCT COUNT(*) As relevance, id, file_Title, file_Desc FROM Listings 
  WHERE ((file_Title LIKE '%John%'
    OR file_Desc LIKE '%John%')
    OR (file_Title LIKE '%Deere%' 
    OR file_Desc LIKE '%Deere%') 
    OR (file_Title LIKE '%Lawn%' 
    OR file_Desc LIKE '%Lawn%') 
    OR (file_Title LIKE '%Tractors%' 
    OR file_Desc LIKE '%Tractors%') ) 
 GROUP BY id 
 ORDER BY relevance DESC

このコードを使用すると、DB から 275 件の結果が得られます。私の問題は、行で見つかったキーワードの数で実際に並べ替えられないことです。代わりにIDで結果を並べ替えるようです。「GROUP BY id」を削除すると、すべての結果ではなく 1 つの結果のみが返されます。これは本当に面倒です!

また、データベースでFULLTEXTに移行しようとしましたが、それもうまくいかないように見えるので、LIKE %Keyword%構文に固執したいと思います。

どんな助けでも大歓迎です!ありがとう!

4

2 に答える 2

2

まったく別のアプローチを提案します。あなたのアプローチは面倒で、非効率的で、DB に負担がかかり、データベースに追加されるレコードが増えると非常に遅くなる可能性があります。

私が提案するのは次のとおりです。

  1. キーワード用に別のテーブルを作成します。
  2. インデックスに登録したくない非キーワード (一般的な英語の前置詞など) のリストを作成して、それらが含まれないようにします。それらのリストは、おそらくオンラインですぐに入手できます。
  3. 新しいエントリが追加されたら、文字列を個別のキーワードに分割し、ステップ 2 のキーワードを省略して、ステップ 3 で作成したテーブルに挿入します (まだテーブルにない場合)。
  4. 外部キーがキーワード テーブルを指している別のテーブルで、classifed_ad をキーワードに関連付けます。

クラシファイド広告が編集された場合は、ステップ 3 と 4 を再度実行する必要があります (つまり、ステップ 4 で挿入されたキーワードが関連付けテーブルから削除され、キーワードが再度分析されて、分類された広告に再度関連付けられます)。

この構造ができたら、関連テーブルを検索して、一致したキーワードの数で並べ替えるだけです。追加の列を追加して、記事内でのそのキーワードの出現回数を入れることもできるので、それによっても注文できます。

それははるかに高速になります。

私は以前、似たようなことをするSphiderと呼ばれるスクリプトを使用していました。まだ維持されているかどうかはわかりませんが、解析する Web ページで非常によく似た方法で機能します。

于 2012-11-11T04:24:47.687 に答える
0

に問題があるとおっしゃっていましたがFULLTEXT、戻ってもう一度やり直すことを強くお勧めします。FULLTEXT インデックスと検索は、ユーザーが行っていることを行うように設計されており、MATCH コマンドが WHERE 句で使用されると、MySQL は自動的に行を関連性の高いものから低いものへと並べ替えます。

FULLTEXT の詳細については、http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html を参照してください

また、同じページの Patrick O'Lone によるコメントに特に注意してください。その一部を以下に引用します...

ドキュメントでは、IN BOOLEAN MODE はほぼ常に関連度 1.0 を返すことに注意してください。意味のある関連性を得るには、次のことを行う必要があります。

SELECT MATCH('Content') AGAINST ('keyword1 keyword2') as Relevance FROM table WHERE MATCH ('Content') AGAINST('+keyword1 +keyword2' IN BOOLEAN MODE) HAVING Relevance > 0.2 ORDER BY Relevance DESC

BOOLEAN MODE を使用する WHERE 句と組み合わせて関連性要因を取得するために、通常の関連性クエリを実行していることに注意してください。BOOLEAN MODE は BOOLEAN 検索の要件を満たすサブセットを提供し、関連クエリは関連係数を満たし、HAVING 句 (この場合) はドキュメントが検索に関連していることを保証します (つまり、スコアが 0.2 未満のドキュメント)は無関係と見なされます)。これにより、関連性で並べ替えることもできます。

于 2012-11-11T05:40:58.243 に答える