2013-07-17 31 views
3

這是MySQL/PHP場景:如何通過mysql/php中的最佳匹配對搜索結果進行排名?

假設我需要根據他們的資格找到專業人員。現在假定搜索輸入是「CA,BA」。

  1. 我希望它來搭配,「CA」,「MCA」,「BCA」,「MBA」,......可以很容易地通過在MySQL中使用LIKE甚至REGEXP,如果我無視性能做了,現在'CA'是完全匹配的,所以我想要一個CA的用戶在他的個人資料中排名高於其他人。
  2. 由於我正在搜索兩個條目,我希望根據該人是否匹配(或部分匹配)兩個資格而不是單個資格來對結果列表進行進一步排序。

對於第一個我想我可以使用levenshtein距離,但我擔心表現。但對於第二個我根本不知道。所以我的問題是如何以最高效的方式做到這一點?

所有的想法,歡迎

回答

0

萊文斯坦將可能是緩慢的,但有可能

做一個查詢每個值檢查,得到了MIN lenvenshtein距離。對2個查詢執行UNION ALL,並將其用作子查詢以選擇最小距離的人員和SUM,然後按降序排列該值。

編輯

假設你可以重新設計表格

有3個表: -

專業 標識 名稱 的表...

表資格的 Id QualificationName

LinkTable ProfessionalId QualificationId

然後做AA查詢確實針對資格的Levenshtein距離(這應該意味着僅做每資格,不是每個人資格)子查詢: -

SELECT Name, SUM(Relevancy) AS SumRelevancy 
FROM 
(
    SELECT a.Name, MIN(c.Relevancy) AS Relevancy 
    FROM Professionals a 
    INNER JOIN LinkTable b ON a.Id = b.ProfessionalId 
    INNER JOIN 
    (
     SELECT QualificationId, LEVENSHTEIN('CA', QualificationName) AS Relevancy FROM Qualifications 
    ) c ON b.QualificationId = c.QualificationId 
    GROUP BY a.Name 
    UNION ALL 
    SELECT a.Name, MIN(c.Relevancy) AS Relevancy 
    FROM Professionals a 
    INNER JOIN LinkTable b ON a.Id = b.ProfessionalId 
    INNER JOIN 
    (
     SELECT QualificationId, LEVENSHTEIN('BA', QualificationName) AS Relevancy FROM Qualifications 
    ) c ON b.QualificationId = c.QualificationId 
    GROUP BY a.Name 
) Sub1 
GROUP BY Name 
ORDER BY SumRelevancy 
+0

可以工作,但即使我在一個存儲過程中關閉了這個邏輯,我認爲考慮到幾千個用戶需要查看的數據庫會非常慢。也許我可以事先在參考表中存儲值的soundex ...但我仍然認爲,如果我讓mysql自己做這件事情,它會真的很慢?沒有任何方法可以將php和mysql結合在一起使事情更優化嗎? – Bluemagica

+0

任何這樣的事情都會變得緩慢。Levenshtein並不是那麼快,因爲它需要比較你不能預先計算的值。由於第一個字符必須匹配,所以Soundex是無用的,並且它是爲歐洲名稱設計的,對於一般性詞語和非歐洲名稱不適用。你可以改變數據庫設計嗎? – Kickstart

+0

如果您可以重新設計表格,請編輯以提出解決方案 – Kickstart

0

我會搜索精確的匹配,扔在一個數組,然後搜索就像比賽和陣列中的扔。

最後我會做一個array_diff,結果就在那裏。

相關問題