0

重複の可能性:
このコードの結果を並べ替えるには?

ユーザーが質問を検索できるようにする検索機能を作成すると、質問内の一致する単語の数を数えることで、上位 5 つの最も一致する結果が表示されます。基本的に、一致する単語の数が最も多い質問である最良の一致を最初に表示する順序が必要です。
これが私が持っているコードです。

<?php
include("config.php");
$search_term = filter_var($_GET["s"], FILTER_SANITIZE_STRING); //User enetered data
$search_term = str_replace ("?", "", $search_term); //remove any question marks from string
$search_count = str_word_count($search_term);  //count words of string entered by user
$array = explode(" ", $search_term); //Seperate user enterd data



foreach ($array as $key=>$word) {
$array[$key] = " title LIKE '%".$word."%' "; //creates condition for MySQL query
}

$q = "SELECT * FROM posts WHERE  " . implode(' OR ', $array); //Query to select data with word matches
$r = mysql_query($q);
$count = 0; //counter to limit results shown
    while($row = mysql_fetch_assoc($r)){
        $thetitle = $row['title']; //result from query
        $thetitle = str_replace ("?", "", $thetitle);  //remove any question marks from string
        $title_array[] = $thetitle;  //creating array for query results
        $newarray = explode(" ", $search_term); //Seperate user enterd data again
            foreach($title_array as $key => $value) {
                $thenewarray = explode(" ", $value); //Seperate each result from query
                $wordmatch = array_diff_key($thenewarray, array_flip($newarray));
                $result = array_intersect($newarray, $wordmatch);
                $matchingwords = count($result); //Count the number of matching words from
                                                 //user entered data and the database query
            }

if(mysql_num_rows($r)==0)//no result found
    {
    echo "<div id='search-status'>No result found!</div>";
    }
else //result found
    {
    echo "<ul>";
        $title = $row['title'];
        $percentage = '.5'; //percentage to take of search word count
        $percent = $search_count - ($search_count * $percentage); //take percentage off word count
        if ($matchingwords >= $percent){
        $finalarray = array($title => $matchingwords);

        foreach( $finalarray as $thetitle=>$countmatch ){


?>
    <li><a href="#"><?php echo $thetitle ?><i> &nbsp; <br />No. of matching words: <?php echo $countmatch; ?></i></a></li>
<?php


                }
                $count++;
        if ($count == 5) {break;
        }
                }else{



            }
    }
echo "</ul>";
}

?>
何かを検索すると、次のように表示されます。
ここに画像の説明を入力
各質問の下に一致する単語の数を入力しますが、順序が正しくありません。データベースから 50% の単語が一致する最初の 5 つの質問だけが表示されます。一致する単語の数が最も多い上位 5 つを表示したいと考えています。
これを行うには、どのコードを追加する必要があり、どこに配置しますか?
ありがとう

4

2 に答える 2

1

これがあなたの問題に対する私の見解です。多くのことが変更されました。

  • mysql_PDOに置き換えられた関数
  • 匿名関数の使用は、PHP 5.3 が必要であることを意味します
  • メインロジックが再構築されました(結果の処理を追うのは本当に難しいので、必要なもの、たとえばそのポイントが欠けている可能性があります$percentage

これは複雑に見えるかもしれませんが、最新のプラクティス (PDO、無名関数) を学ぶのが早ければ早いほど、うまくいくと思います。

<?php
/**
 * @param string $search_term word or space-separated list of words to search for
 * @param int $count
 * @return stdClass[] array of matching row objects
 */
function find_matches($search_term, $count = 5) {
    $search_term = str_replace("?", "", $search_term);
    $search_term = trim($search_term);
    if(!strlen($search_term)) {
        return array();
    }
    $search_terms = explode(" ", $search_term);

    // build query with bind variables to avoid sql injection
    $params = array();
    $clauses = array();

    foreach ($search_terms as $key => $word) {
        $ident = ":choice" . intval($key);
        $clause = "`title` LIKE {$ident}";
        $clauses []= $clause;
        $params [$ident] = '%' . $word . '%';
    }

    // execute query
    $pdo = new PDO('connection_string');
    $q = "SELECT * FROM `posts` WHERE  " . implode(' OR ', $clauses);
    $query = $pdo->prepare($q);
    $query->execute($params);
    $rows = $query->fetchAll(PDO::FETCH_OBJ);

    // for each row, count matches
    foreach($rows as $row) {
        $the_title = $row->title;
        $the_title = str_replace("?", "", $the_title);

        $title_terms = explode(" ", $the_title);
        $result = array_intersect($search_terms, $title_terms);
        $row->matchcount = count($result);
    }

    // sort all rows by match count descending, rows with more matches come first
    usort($rows, function($row1, $row2) {
        return - ($row1->matchcount - $row2->matchcount);
    });

    return array_slice($rows, 0, $count);
}
?>

<?php
    $search_term = filter_var($_GET["s"], FILTER_SANITIZE_STRING);
    $best_matches = find_matches($search_term, 5);
?>

<?php if(count($best_matches)): ?>
    <ul>
    <?php foreach($best_matches as $match): ?>
        <li><a href="#"><?php echo htmlspecialchars($match->title); ?><i> &nbsp; <br/>No. of matching words: <?php echo $match->matchcount; ?></i></a></li>
    <?php endforeach; ?>
    </ul>
<?php else: ?>
    <div id="search-status">No result found!</div>
<?php endif; ?>
于 2012-08-05T14:50:31.723 に答える
0

宣言asort($finalarray);の後に追加してみてください:$finalarray = array($title => $matchingwords);

...

if ($matchingwords >= $percent){
    $finalarray = array($title => $matchingwords);
    asort($finalarray);

....

配列を値の昇順で並べ替える必要があります

于 2012-08-05T13:58:01.707 に答える