2012-10-15 78 views
11

我是currenlty建設一個網上商店。這家商店允許用戶通過category過濾產品,和幾個可選的,額外的過濾器,例如brandcolorPHP,MySQL,高效的標籤驅動搜索算法

目前,各種屬性存儲在不同的地方,但我想切換到基於標籤的系統。理想情況下,我的數據庫應存儲的標籤數據如下:

  • product_id
  • tag_url_alias(唯一的)
  • tag_type(唯一)(類別,product_brand,product_color等)
  • tag_value(不是唯一)

第一個目標

我想搜索product_id的與任何地方相關的1-5特定標籤。標籤是從一個搜索引擎優化友好的網址中提取的。所以我將檢索每個標籤的唯一字符串(tag_url_alias),但我不知道tag_type。 搜索將是一個路口,所以我的搜索應該返回匹配所有提供tags的是,product_id的。

第二個目標

除了顯示匹配當前過濾器的產品,我也想顯示其他類別和用戶可能提供其過濾器的產品數。

舉例來說,我目前的搜索是相匹配的標籤的產品:

Shoe + Black + Adidas 

現在,店裏的顧客可能會尋求在所產生的產品,不知這黑皮鞋等品牌都有提供。所以他們可能會去「品牌」過濾器,並選擇任何其他上市品牌。比方說,他們有2個不同的選項(在實踐中,這將可能有更多的),導致下面的搜索:

Shoe + Black + Nike > 103 results 
Shoe + Black + K-swiss > 0 results 

在這種情況下,如果他們看到的品牌「蓋世」列爲可用在他們的篩選器中選擇,他們的搜索將返回0結果。

這對用戶來說顯然是相當令人失望......我更想知道將「品牌」從「adidas」切換到「k-swiss」將會產生0結果,並且只需從過濾器中刪除整個選項。

同樣的事情也適用於種類,顏色等

在實踐中,這將意味着一個頁面視圖不僅返回我的首要目標描述的過濾產品列表,但潛在的數百個類似但不同的列表。一個用於替換另一個過濾器值的每個過濾器值,或者添加到現有過濾器值中。

容量

我懷疑我的數據庫最終將包含:獨特的標籤

和1.000之間250它將包含:

10.000和100.000之間獨特產品

現在的想法

我做了一些谷歌搜索,發現下面的文章:http://www.pui.ch/phred/archives/2005/06/tagsystems-performance-tests.html

這一條來看,運行數百個查詢,實現了第二個目標,將是一個痛苦而緩慢的路線。 「toxy」的例子可能適合我的需求,對我的第一個目標來說可能是可以接受的,但對於第二個目標來說,這將是無法接受的緩慢。

我在想我可能會運行匹配1 tag的單個查詢,它與product_id相關聯,緩存這些查詢,然後計算結果的交點。但是,我是否在MySQL中計算這些交叉點?或在PHP中?如果我使用MySQL,是否有一種特殊的方式來緩存這些單獨的查詢,或者提供所有我需要的正確索引?

我會想像它甚至有可能甚至緩存這兩個集合中的兩個之間的交集。由於tag_type只能有一個特定值,所以交叉點的數量會受到限制,但我不確定如何有效地管理這種類型的緩存。再次,我不知道我是否應該在MySQL或PHP中執行此操作。如果我在MySQL中這樣做,將存儲和組合這種類型的緩存結果的最佳方式是什麼?

+1

這是一篇論文:D – dynamic

+1

嗯,這就是我所說的一個問題!祝賀先生。 – Weacked

+0

謝謝!我敢打賭,答案會爲我提供很多新的知識! –

回答

2

使用sphinx search engine可以爲你創造這種神奇。它的速度非常快,甚至可以處理字形,對SEO請求有用。根據獅身人面像,製作一個文檔 - 「產品」,通過標籤索引,爲查詢選擇合適的排序器(例如,MATCH_ALL_WORDS),並使用不同的標籤組合運行批量請求以獲得最佳結果。 不要忘記使用memcahed或任何其他的cachers。

+0

好吧,這聽起來很有趣。我不知道他們的SQL支持是否包含諸如query @ eX0du5建議的內容......然後,我可能會同時使用專門的高性能搜索引擎和幾個非常聰明的查詢,而不是一堆簡單的查詢。 –

+0

Sphinx支持類似mysql的查詢語法模式,稱爲SphinxQL,但我更喜歡使用本地調用 –

2

我還沒有測試過,但它應該有可能有一個查詢來滿足您的第二個目標,而不是觸發幾百個查詢... 下面的查詢說明了這應該如何工作。 這個想法是一次結合三個不同的請求,並由專用值組合,只收集那些有任何結果的請求。

SELECT t1.product_id, count(*) FROM tagtable t1, tagtable t2, tagtable t3 WHERE 
t1.product_id = t2.product_id AND 
t2.product_id = t3.product_id AND 
t1.tag_type='yourcategoryforShoe' AND t1.tag_value='Shoe' AND 
t2.tag_type='product_color' AND t2.tag_value='Black' AND 
t3.tag_type='brand' 
GROUP BY t3.tag_value 
HAVING count(*) > 0 
+0

這聽起來很聰明!我將不得不運行一些性能測試... –