/    Sign up×
Community /Pin to ProfileBookmark

Ranking Search Results

Hi,

I’ve successfully compiled a Search Engine using PHP to search my MySQL database, matching keywords and returning results. However, I need a way to rank the results so that if one entry in the database has 3 words matching it should appear before an entry with only 1 word matching. At the moment results are returned in the order they are in the database.

Code:
[FONT=”Courier New”]<?php include(‘header.php’);

echo”<div id=mainpage><h2>Questions: (click for the answer)</h2><br><br>”;

//This is a working script
//Make sure to go through it and edit database table filelds that you are seraching
//This script assumes you are searching 3 fields

//specify how many results to display per page
$limit = 10;

// Get the search variable from URL
$var = @$_POST[‘question’] ;
//trim whitespace from the stored variable
$trimmed = trim($var);

//separate key-phrases into keywords
$trimmed_array = explode(” “,$trimmed);
// check for an empty string and display a message.
if ($trimmed == “”) {
$resultmsg = “<h2>Search Error</h2>Please enter a question!<br><a href=index.php>Click here to go back</a>” ;
}

// check for a search parameter
if (!isset($var)){
$resultmsg = “<p>Search Error</p><p>We don’t seem to have a search parameter! </p>” ;
}
// Build SQL Query for each keyword entered
foreach ($trimmed_array as $trimm){

// EDIT HERE and specify your table and field names for the SQL query
$query = “SELECT * FROM Answers WHERE Keywords LIKE “%$trimm%”” ;
// Execute the query to get number of rows that contain search kewords
$numresults=mysql_query ($query);
$row_num_links_main =mysql_num_rows ($numresults);

// next determine if ‘s’ has been passed to script, if not use 0.
// ‘s’ is a variable that gets set as we navigate the search result pages.
if (empty($s)) {
$s=0;
}

// now let’s get results.
$query .= ” LIMIT $s,$limit” ;
$numresults = mysql_query ($query) or die ( “Couldn’t execute query” );
$row= mysql_fetch_array ($numresults);

//store record id of every item that contains the keyword in the array we need to do this to avoid display of duplicate search result.
do{

//EDIT HERE and specify your field name that is primary key
$adid_array[] = $row[ ‘ID’ ];
}while( $row= mysql_fetch_array($numresults));
} //end foreach

if($row_num_links_main == 0 && $row_set_num == 0){
$resultmsg = “<h2>Search results for:” . $trimmed .”</h2>Sorry, your search returned zero results, try rephrasing your question<br><a href=index.php>Click here to go back</a>” ;
}
//delete duplicate record id’s from the array. To do this we will use array_unique function
$tmparr = array_unique($adid_array);
$i=0;
foreach ($tmparr as $value) {
$newarr[$i] = $value;
$i++;
}

// display what the person searched for.
if( isset ($resultmsg)){
echo $resultmsg;
exit();
}

foreach($newarr as $value){

// EDIT HERE and specify your table and field names for the SQL query
$query_value = “SELECT * FROM Answers WHERE ID = ‘$value'”;
$num_value=mysql_query ($query_value);
$row_linkcat= mysql_fetch_array ($num_value);
$row_num_links= mysql_num_rows ($num_value);

//now let’s make the keywods bold. To do that we will use preg_replace function.
//EDIT parts of the lines below that have fields names like $row_linkcat[ ‘field1’ ]
//This script assumes you are searching only 3 fields. If you are searching more fileds make sure that add appropriate line.
$titlehigh = preg_replace ( “‘($var)’si” , “<b>1</b>” , $row_linkcat[ ‘Keywords’ ] );

foreach($trimmed_array as $trimm){
if($trimm != ‘b’ ){
//IF you added more fields to search make sure to add them below as well.
$titlehigh = preg_replace( “‘($trimm)’si” , “<b>1</b>” , $titlehigh);
$qq = $row_linkcat[‘Question’];
$id = $row_linkcat[‘ID’];
}
//end highlight

?>

<?php
if($badger!=$id){
$badger=x;
echo “<a href=answer.php?id=$id>$qq</a><br>”;
$badger=$id;
}
?>

<?php
} //end foreach $trimmed_array
if($row_num_links_main > $limit){
// next we need to do the links to other search result pages
if ($s>=1) { // do not display previous link if ‘s’ is ‘0’
$prevs=($s-$limit);
echo “<div align=’left’><a href=’$PHP_SELF?s=$prevs&q=$var&catid=$catid’>Previous ” .$limit. “</a></div>”;
}
// check to see if last page
$slimit =$s+$limit;
if (!($slimit >= $row_num_links_main) && $row_num_links_main!=1) {
// not last page so display next link
$n=$s+$limit;
echo “<div align=’right’><a href=’$PHP_SELF?s=$n&q=$var&catid=$catid’>Next ” .$limit. “</a></div>”;
}
}
} //end foreach $newarr

echo “</div>”;

include(‘footer.php’);?> [/FONT]

to post a comment
PHP

4 Comments(s)

Copy linkTweet thisAlerts:
@Phill_PaffordOct 29.2008 — If your running MySQL 5.x you could use

[CODE]
ORDER BY LENGTH(your_field_here) DESC
[/CODE]


This should go before the LIMIT and after the GROUP BY or any other conditions

No need to code PHP for this
Copy linkTweet thisAlerts:
@JustinOct 29.2008 — If I'm mistaken, ordering by length would just order it by the length of the field? Isn't he trying to order it by the number of matches?

I may have missed something, didn't look too hard at the example.
Copy linkTweet thisAlerts:
@badgerwebauthorNov 11.2008 — Exactly Justin, please say there's an easy way to 'rank' the results...
Copy linkTweet thisAlerts:
@JustinNov 11.2008 — From what I have seen, It looks like the best way to do this is to read it all into a php array then use php to sort the array based on matches. So basically once you have your result from mysql, you count your keywords from there.

I don't know any better solutions off the top of my head, but if you come across any please post it back here.
×

Success!

Help @badgerweb spread the word by sharing this article on Twitter...

Tweet This
Sign in
Forgot password?
Sign in with TwitchSign in with GithubCreate Account
about: ({
version: 0.1.9 BETA 5.13,
whats_new: community page,
up_next: more Davinci•003 tasks,
coming_soon: events calendar,
social: @webDeveloperHQ
});

legal: ({
terms: of use,
privacy: policy
});
changelog: (
version: 0.1.9,
notes: added community page

version: 0.1.8,
notes: added Davinci•003

version: 0.1.7,
notes: upvote answers to bounties

version: 0.1.6,
notes: article editor refresh
)...
recent_tips: (
tipper: @AriseFacilitySolutions09,
tipped: article
amount: 1000 SATS,

tipper: @Yussuf4331,
tipped: article
amount: 1000 SATS,

tipper: @darkwebsites540,
tipped: article
amount: 10 SATS,
)...