2013-03-23 113 views
0

我想創建一個簡單搜索我正在處理的網站。我有我的數據庫中的項目,都保存一個特定的類別ID,並可以選擇鏈接到多個標籤。按類別搜索自定義網站

我想採取任何搜索詞進來,並查詢category.name和tag.name字段來查找匹配這些條款的項目。

我正在尋找諮詢如何建立一個高效/快速查詢,這是否和訂單的匹配最接近該項目的結果(最匹配)

這裏是我的相關表的快速版本:

item

id |類別|標題|說明

類別

ID |名稱| parentId的

標籤

ID |名稱|使用

item_tag

的itemId | tagId

回答

1

我仍然沒有完全明白你想要什麼。那麼,這是我們討論的第一個版本。
我建議你創建一個視圖,如下所示:

CREATE OR REPLACE VIEW `search_view` AS 
SELECT 
    i.id AS `item_id`, 
    i.title AS `item_title`, 
    c.id AS `cat_id`, 
    c.name AS `cat_name`, 
    t.id AS `tag_id`, 
    t.name AS `tag_name` 
FROM item AS i 
LEFT OUTER JOIN item_tag AS it 
    ON (i.id = it.itemId) 
LEFT OUTER JOIN tag AS t 
    ON (it.tagId = t.id) 
LEFT OUTER JOIN category AS c 
    ON (i.category = c.id) 
WHERE ((t.id IS NOT NULL) OR (c.id IS NOT NULL)); 

然後你使用一些視圖查詢附近

SELECT 
    *, 
    (
    IF(tag_name like ?, 2, 0) 
    + IF(cat_name like ?, 4, 0) 
    + IF(item_title like ?, 1, 0) 
) AS `priority` 
    FROM search_view 
GROUP BY item_id 
ORDER BY SUM(priority); 

在上面的代碼沒有測試。舉報你的任何問題

[第一版]您使用PHP,不是嗎?那麼,你可以用PHP string functions來標準化你的查詢;一種方法是用'|'替換每個',',刪除多餘的空格並執行以下查詢:[我將給出一個使用@VAR的例子(實際上你會用你的輸入字符串替換它)]

SET @VAR = 'notebook|samsung'; 
SELECT 
    *, 
    (
    IF (tag_name REGEXP CONCAT('.*(', @VAR, ').*'), 2, 0) 
    + IF (cat_name REGEXP CONCAT('.*(', @VAR, ').*'), 4, 0) 
    + IF (item_title REGEXP CONCAT('.*(', @VAR, ').*'), 1, 0) 
) AS `priority` 
    FROM search_view 
ORDER BY priority DESC; 

這次我測試過了。是的,你可以使用MySQL函數,約REPLACE(REPLACE(@VAR,' ',''), ',', '|')。但我建議你用PHP(或者Java,Python等)來做。

+0

我還沒有真正與意見。上述部分是需要在每個查詢之前運行還是僅在創建連接時運行一次? – Helto 2013-03-23 22:14:55

+0

我真的很喜歡你的解決方案,並且你添加了對標題的搜索並給予不同領域的權重。如果您有機會,您是否願意解釋我可以如何修改這個以適應多種搜索條件?它們將以逗號分隔的字符串形式出現。 – Helto 2013-03-24 22:40:04

+0

@你好,你創建視圖一次,然後你從他們的查詢,就好像他們是普通表(!)。如果您需要更新您的視圖,請運行: 'CREATE OR REPLACE VIEW AS '。 關於你的最後一個疑問,我會盡力幫助你(今天如果可能的話),當我有時間(讓我們看看如果我能) – 2013-03-26 18:50:47

0
SELECT item.* 
FROM items 
LEFT JOIN categories 
     ON categories.name = '< input name >' 
     AND categories.id = items.category 
LEFT JOIN item_tags 
     AND item_tags.itemId = items.id 
LEFT JOIN tags 
     ON tags.name = '< input name >' 
     AND tags.id = item_tags.tagId 
WHERE categories.id IS NOT NULL 
    OR tags.id IS NOT NULL 
ORDER BY COUNT(items.id) DESC; 

這可能不是最快的方法。基本上,你會留下加入類別和標籤的項目,同時確保類別和標籤有正確的名稱。過濾出與where子句中的類別或item_tag不匹配的所有項目。

另一種選擇是創建臨時表。使用正確的名稱爲所有類別創建一個,使用正確名稱的所有類別創建一個。你可以選擇items WHERE items.id IN categories_table OR items.id IN tags_table

+0

我認爲這將讓我在正確的軌道上,但表item_tag只映射標籤的物品,所以標籤表格需要被加入,以及搜索編輯我的職務名稱 – Helto 2013-03-23 03:28:11

+0

。現在應該是正確的。 – 2013-03-24 01:29:39

相關問題