2016-08-13 30 views
1

我想基於PHP/MySQL做一個關於視頻的簡單搜索引擎(就像一個非常簡單的Shutterstock)。 所以這裏的交易。一個視頻有多個關鍵字(或標籤)。用戶在搜索欄中鍵入一些關鍵字,然後他獲得這些關鍵字在視頻中的列表(按相關性排序)。在Mysql中構建標籤搜索引擎 - 排序時遇到的問題

我創建了3個MySQL表:

  • 視頻:VIDEO_ID,VIDEO_NAME,video_format,等等...
  • 標籤:TAG_ID,TAG_NAME
  • video_tag: video_id,tag_id //鏈接標籤和視頻的連接表(視頻具有一個或多個關鍵字,一個關鍵詞由一個或多個視頻使用)

結果的相關性是很重要的,這裏是邏輯:

如果在搜索欄中用戶類型:水,木,自然,結果會是這樣:

(1) the videos which associate water, wood and nature 
(2) the videos which associate water and wood 
(3) the videos which associate water and nature 
(4) the videos which associate wood and nature 
(5) the videos which associate water 
(6) the videos which associate wood 
(7) the videos which associate nature 

所以我有一個做在PHP中的算法建立這種多維數組:

[0] [water, wood, nature] 
[1] [water, wood] 
[2] [water, nature] 
[3] [nature, water] 
[4] [wood, nature] 
[5] [water] 
[6] [wood] 
[7] [nature] 

接下來,我把這個數組中的MySQL的請求,這裏就是我堅持......我有什麼我的要求:

SELECT video.video_id,video.video_name, GROUP_CONCAT(tag.tag_name) AS tags 

    FROM 
     video_tag 
     INNER JOIN video 
      ON video_tag.video_id = video.video_id 
     INNER JOIN tag 
      ON tag.tag_id = video_tag.tag_id 

    GROUP BY video_id 

    HAVING tags LIKE '%water%' AND tags LIKE '%wood%' AND tags LIKE '%nature%.' 
    OR tags LIKE '%water%' AND tags LIKE '%wood%' 
    OR tags LIKE '%water%' AND tags LIKE '%nature%' 
    OR tags LIKE '%wood%' AND tags LIKE '%nature%' 
    OR tags LIKE '%water%' 
    OR tags LIKE '%wood%' 
    OR tags LIKE '%nature%' 

但是結果的順序是不正確的。一切都按video_id排序。

video_id   video_name   tags 
1     video 01   wood, keyword4, keyword5, keyword 6, keyword 7 
2     video 02   wood, nature, water, keyword 6 
3     video 03   nature, water, keyword 7 

我想要的順序如下:

video_id   video_name   tags 
2     video 02   wood, nature, water, keyword 6 
3     video 03   nature, water, keyword 7 
1     video 01   wood, keyword4, keyword5, keyword 6, keyword 7 

有MySQL中的方式來獲得該請求的「自然」順序排序的結果?我是否以正確的方式做這件事?有人遇到過這種麻煩,能幫助我嗎? :)

回答

1

謝謝。隨着你的提議,我終於意識到自己過於複雜了。無需多維數組或組合邏輯的......

這裏是我找到了解決辦法:

SELECT DISTINCT video.video_name, GROUP_CONCAT(tag.tag_name) AS tags 

FROM 
    video_tag 
    INNER JOIN video 
     ON video_tag.video_id = video.video_id 
    INNER JOIN tag 
     ON tag.tag_id = video_tag.tag_id 

WHERE tag.tag_name= 'wood' OR tag.tag_name = 'nature' OR tag.tag_name = 'corporate' 

GROUP BY video_id 
ORDER BY COUNT(*) DESC; 

那樣,我選擇一個有所需標籤的鏈接的所有視頻。然後,我只計算一個視頻有多少個標籤......並按照這個數字排序......最後,我的麻煩很簡單。

很抱歉的干擾;)

+0

開關的NoSQL技術,不考慮複雜的事情(: – num8er

+0

這是很有趣的我可以打擾你用樣本數據的樣本數據庫,所以我可以看到你。看到了嗎?也許鏈接一個zip文件sql ... – enchance

1

首先,可以簡化having子句:

having max(tag_name = 'water') > 0 or 
     max(tag_name = 'nature') > 0 or 
     max(tag_name = 'wood') > 0 

換句話說,你不需要處理字符串,你可以使用原來的標籤。通過不同的匹配標籤的數量

order by ((max(tag_name = 'water') + 
      (max(tag_name = 'nature') + 
      (max(tag_name = 'wood') 
     ) desc 

此命令:

然後,您可以親近你想用這個簡單的邏輯是什麼。我不確定爲什麼兩個匹配標籤的排序有所不同。

您的訂購似乎更喜歡水>木材>性質,所以做:

order by ((max(tag_name = 'water') + 
      (max(tag_name = 'nature') + 
      (max(tag_name = 'wood') 
     ) desc, 
     max(tag_name = 'water') desc, 
     max(tag_name = 'nature') desc, 
     max(tag_name = 'wood) desc 

注意,在數值上下文中,布爾值被視爲一個整數,以「1」爲真,「0 「爲虛假。這就是爲什麼max()+適用於這些查詢。