2011-06-27 56 views
21

這裏就是我想要做的:對mysql中的多個字段進行加權搜索的最佳方法?

  • 對陣我的表
  • 以便通過匹配的領域和相關的重要結果的多個領域的搜索主題(按順序)
例如:

例如:假設我有博客。然後有人搜索「php」。結果會出現這樣:

  • 首先,通過相關性排序
  • 則現場「標題」,在比賽中,爲現場「身體」的比賽中,通過相關性排序太
  • 等在指定的字段上...

我實際上做了一個PHP中的類,但它使用了很多UNION(很多!)並隨着搜索主題的大小而增長。所以我擔心性能和DOS問題。有人有這方面的線索嗎?

回答

29

可能做一個加權搜索/結果的這種做法是適合你:

SELECT *, 
    IF(
      `name` LIKE "searchterm%", 20, 
     IF(`name` LIKE "%searchterm%", 10, 0) 
    ) 
     + IF(`description` LIKE "%searchterm%", 5, 0) 
     + IF(`url`   LIKE "%searchterm%", 1, 0) 
    AS `weight` 
FROM `myTable` 
WHERE (
    `name` LIKE "%searchterm%" 
    OR `description` LIKE "%searchterm%" 
    OR `url`   LIKE "%searchterm%" 
) 
ORDER BY `weight` DESC 
LIMIT 20 

它使用子查詢中選擇要訂購的結果提供的重量。在這種情況下搜索到三個字段,您可以指定每個字段的權重。它可能比聯盟便宜,並且可能是純MySQL中更快的方法之一。

如果你有更多的數據並且需要更快的結果,你可以考慮使用類似Sphinx或Lucene的東西。

+0

我喜歡這種方法!你能解釋一下在FROM之前IF中發生了什麼事嗎?我不使用複雜的查詢=/ –

+2

基本上它是一個IF函數,如果條件(第一個參數)爲true,則將使用第二個參數(權重),否則將使用第三個參數(0-權重)。本手冊包含所有詳細信息:http://dev.mysql.com/doc/refman/5.0/en/control-flow-functions.html#function_if – hakre

+0

非常好!所以如果它出現在名稱(不是在開始處),說明和網址,它會得到16的權重? (10 + 5 + 1) –

1

您應該使用專用索引器將所有數據預取到優化的可搜索索引中。 Sphinx和類似的產品做得非常好。

8

您可以將多個mysql MATCH()值一起添加,首先將它們的權重相乘。

簡化當然...

'(MATCH(column1) AGAINST(\''.$_GET['search_string'].'\') * '.$column1_weight.') 
+ (MATCH(column2) AGAINST(\''.$_GET['search_string'].'\') * '.$column2_weight.') 
+ (MATCH(column3) AGAINST(\''.$_GET['search_string'].'\') * '.$column3_weight.') 
AS relevance' 

然後

'ORDER BY relevance' 
+0

如果您的權重設置正確,它會按照所需的順序放置它們。 – dqhendricks

+0

你能舉個例子說明如何設置權重嗎? –

+0

@hugo_leonardo體重取決於標題中的比賽與身體相比多重要多少。所以如果標題匹配比身體匹配重要5倍,則權重分別是5和1。這是否有意義? – dqhendricks

1

我有這個確切的同樣的問題,它是在MySQL的論壇之一完全回答。 Here's the thread.一種長線程(因爲我有點囉嗦),但回報正是你想要的。

+0

很有意思! +1(: –

+0

@ hugo_leonardo - 是的,這兩個人的迴應給了非常深思熟慮的答案。 –

+2

@PeteWilson:請將相關引號添加到您的文章中,因爲外部鏈接可能會中斷。 – jor

相關問題