2010-07-02 96 views
2

我試圖加入多個表並對它們執行全文搜索。不同字段的多個表上的MySQL全文搜索

大多數表格是不相關的,但具有相似的字段。

我有全文搜索工作,但我需要能夠創建從結果這是下一步的鏈接,但我不瘦K它會工作,因爲我沒有得到足夠的信息enoygh領域。

基本上我想搜索標題和每個表的內容,但我也想搜索我的論壇表,這是主題和消息。主題和消息表是鏈接的。

這個查詢將不會查詢論壇表格,我需要能夠搜索這些表格。

SELECT * FROM (SELECT title, content, 
    MATCH(title, content) AGAINST('folk*' IN BOOLEAN MODE) 
    as score FROM news WHERE MATCH(title, content) 
    AGAINST('folk*' IN BOOLEAN MODE) 
    UNION ALL 
    SELECT title, content, 
    MATCH(title, content) AGAINST('folk*' IN BOOLEAN MODE) 
    as score FROM events WHERE MATCH(title, content) 
    AGAINST('folk*' IN BOOLEAN MODE) 
    UNION ALL 
    SELECT title, content, 
    MATCH(title, content) AGAINST('folk*' IN BOOLEAN MODE) 
    as score FROM blogs WHERE MATCH(title, content) 
    AGAINST('folk*' IN BOOLEAN MODE) 
    UNION ALL 
    SELECT title, content, 
    MATCH(title, content) AGAINST('folk*' IN BOOLEAN MODE) 
    as score FROM honeylands WHERE MATCH(title, content) 
    AGAINST('folk*' IN BOOLEAN MODE) 
    UNION ALL 
    SELECT title, content, 
    MATCH(title, content) AGAINST('folk*' IN BOOLEAN MODE) 
    as score FROM articles WHERE MATCH(title, content) 
    AGAINST('folk*' IN BOOLEAN MODE) 
    UNION ALL 
    SELECT title, content, 
    MATCH(title, content) AGAINST('folk*' IN BOOLEAN MODE) 
    as score FROM info WHERE MATCH(title, content) 
    AGAINST('folk*' IN BOOLEAN MODE) 
    UNION ALL 
    SELECT topicid as title, boardid as content, 
    MATCH(title, content) AGAINST('folk*' IN BOOLEAN MODE) 
    as score FROM articles WHERE MATCH(title, content) 
    AGAINST('folk*' IN BOOLEAN MODE) 
    UNION ALL 
    SELECT topicid as title, message as content, 
    MATCH(title, content) AGAINST('folk*' IN BOOLEAN MODE) 
    as score FROM info WHERE MATCH(title, content) 
    AGAINST('folk*' IN BOOLEAN MODE)) a ORDER BY score DESC 

我應該能夠創建具有黎民字段名,如events.php表的鏈接?ID = 1從記錄中獲取的ID,但我怎麼做到這一點的表主題和消息topic.php?boardid = 1 & topic = 2?

這裏是我的表結構 CREATE TABLE articlesid INT(4)NOT NULL的auto_increment, title VARCHAR(70)NOT NULL默認', content文字NOT NULL, PRIMARY KEY(id) ) ;

 CREATE TABLE `blogs` (
     `id` int(3) NOT NULL auto_increment, 
     `title` varchar(100) NOT NULL default '', 
     `content` text NOT NULL, 
     PRIMARY KEY (`id`) 
    ); 

    CREATE TABLE `events` (
     `id` int(11) NOT NULL auto_increment, 
     `title` varchar(100) NOT NULL default '', 
     `content` text NOT NULL, 
     PRIMARY KEY (`id`) 
    ); 

    CREATE TABLE `honeylands` (
     `id` int(4) NOT NULL auto_increment, 
     `title` varchar(100) NOT NULL default '', 
     `content` text NOT NULL, 
     PRIMARY KEY (`id`) 
    ); 

    CREATE TABLE `info` (
     `id` int(1) NOT NULL auto_increment, 
     `title` varchar(50) NOT NULL default '', 
     `content` text NOT NULL, 
     PRIMARY KEY (`id`) 
    ); 

    CREATE TABLE `messages` (
     `messageid` int(6) NOT NULL auto_increment, 
     `boardid` int(2) NOT NULL default '0', 
     `topicid` int(4) NOT NULL default '0', 
     `message` text NOT NULL, 
     `author` varchar(255) NOT NULL default '', 
     `postdate` datetime default NULL, 
     PRIMARY KEY (`messageid`) 
    ); 

    CREATE TABLE `news` (
     `id` int(4) NOT NULL auto_increment, 
     `title` varchar(100) NOT NULL default '', 
     `content` text NOT NULL, 
     PRIMARY KEY (`id`) 
    ); 


    CREATE TABLE `topics` (
     `topicid` int(4) NOT NULL auto_increment, 
     `boardid` int(2) NOT NULL default '0', 
     `topicname` varchar(255) NOT NULL default '', 
     `author` varchar(255) NOT NULL default '', 
     `counter` int(5) NOT NULL default '0', 
     `sticky` char(1) NOT NULL default 'n', 
     `locked` char(1) NOT NULL default 'n', 
     PRIMARY KEY (`topicid`) 
    ); 

這是我目前如何讓所有的記錄,但沒有使用UNION

SELECT * FROM (SELECT title, content, 
    MATCH(title, content) AGAINST('$keywords*' IN BOOLEAN MODE) 
    as score FROM news WHERE MATCH(title, content) 
    AGAINST('$keywords*' IN BOOLEAN MODE) 
    UNION ALL 
    SELECT title, content, 
    MATCH(title, content) AGAINST('$keywords*' IN BOOLEAN MODE) 
    as score FROM events WHERE MATCH(title, content) 
    AGAINST('$keywords*' IN BOOLEAN MODE) 
    UNION ALL 
    SELECT title, content, 
    MATCH(title, content) AGAINST('$keywords*' IN BOOLEAN MODE) 
    as score FROM blogs WHERE MATCH(title, content) 
    AGAINST('$keywords*' IN BOOLEAN MODE) 
    UNION ALL 
    SELECT title, content, 
    MATCH(title, content) AGAINST('$keywords*' IN BOOLEAN MODE) 
    as score FROM honeylands WHERE MATCH(title, content) 
    AGAINST('$keywords*' IN BOOLEAN MODE) 
    UNION ALL 
    SELECT title, content, 
    MATCH(title, content) AGAINST('$keywords*' IN BOOLEAN MODE) 
    as score FROM articles WHERE MATCH(title, content) 
    AGAINST('$keywords*' IN BOOLEAN MODE) 
    UNION ALL 
    SELECT title, content, 
    MATCH(title, content) AGAINST('$keywords*' IN BOOLEAN MODE) 
    as score FROM info WHERE MATCH(title, content) 
    AGAINST('$keywords*' IN BOOLEAN MODE) 
    UNION ALL 
    SELECT topicname as title,message as content, 
    MATCH(topicname, message) AGAINST('$keywords*' IN BOOLEAN MODE) 
    as score FROM topics t INNER JOIN messages m ON t.topicid=m.topicid 
    WHERE MATCH(topicname, message) 
    AGAINST('$keywords*' IN BOOLEAN MODE)) a ORDER BY score DESC 

回答

3

增加對主題和消息表額外的字段的方式,我碰到這個問題上建立一個搜索一個擁有多種類型內容的網站(電影數據庫)。我希望用戶能夠進行一次搜索並找到演員,電影或角色名稱。

我沒有試圖獲得一個大的SQL語句,而是爲每種類型的內容(movie_title,movie_plot,actor_name,character_name等)進行了匹配,並將該行的id,內容類型和匹配成多維數組的分數。我通常會將每種內容類型限制在前50名比賽中。

我當時能夠根據分數對數組進行排序。然後我會使用id和內容類型來查找每個結果所需的信息。

編輯(添加代碼)

免責聲明:這是舊代碼,並有可能是更有效的做

$topResults = array(); 
$topResults[0] = array('nil', 'nil', 0); 

$movieFound = 0; 
$plotFound = 0; 
$actorFound = 0; 
$characterFound = 0; 

// example of movie title... follow the same procedure for the others 
$sql = "SELECT movies.Movie_ID as mid, MATCH (Movie_Title) AGAINST ('$searchstring') AS Score FROM movies, Rating_Movie_Relationships WHERE MATCH (Movie_Title) AGAINST ('$searchstring') AND Front_Image_File IS NOT NULL AND movies.Movie_ID = Rating_Movie_Relationships.Movie_ID $sqlwhere ORDER BY Score DESC LIMIT 0, 20"; 
$result = @mysql_query($sql); 
while ($row = mysql_fetch_array($result)) { 
    for ($i = 0; $i < count($topResults);$i++){ 
     if ($row['Score'] > $topResults[$i][2]){ 
      for ($j = count($topResults); $j > $i; $j--){ 
       $topResults[$j] = $topResults[$j-1]; 
      } 
      $topResults[$i] = array($row['mid'], 'm', $row['Score'] - $movieWeight); 
      break; 
     } 
    } 
    $movieFound = 1; 
} 

//.... add the other content types here following the movie title example 

for ($i = 0; $i < count($topResults); $i++){ 
    if ($topResults[$i][1] == 'm'){ 
     if ($countMovies < $limit) { 
      $movieTitleDivText .= str_replace('\'','&#39;',createPersonMovieImageLink($topResults[$i][0])); 
      $countMovies++; 
     } 
} 
+0

你有,你是怎麼做到的示例代碼的方式? 你使用了多個查詢嗎? – AdRock 2010-07-02 16:56:25

+0

你會有幾個查詢每個表然後添加到數組? – AdRock 2010-07-02 20:04:05

+0

我對每個表至少有1個查詢,每個查詢的結果放入數組中。 – 2010-07-02 20:33:54