简体   繁体   中英

How do I rank search results by best match in mysql/php?

This is for MySQL/PHP scenario:

Let's say I need to find professionals based on their qualification. Now assume the search input is "CA,BA".

  1. I want it to match, 'CA','MCA','BCA','MBA',... which can be easily done by using LIKE or even REGEXP in MySQL if I disregard performance, now 'CA' is the exact match so I want a user with CA in his profile to be ranked higher than others.
  2. Since I am searching for two entries, I want the resulting list to be further sorted based on whether the person matches(or partially matches) both qualifications instead of a single one.

For the first one I guess I can use levenshtein distance but I am worried about performance. But for the second one I have no idea at all. So my question is how to do this in the most performance efficient way?

All ideas are welcome

I would search for the Exact matches, throw them in an array, then search for the Like matches and throw them in an array.

Finally I would do an array_diff and result is there.

Levenshtein would likely be slow, but possible

Do one query for each value to check, getting the MIN lenvenshtein distance. Do a UNION ALL of the 2 queries, and use that as a sub query to select the person and the SUM of the min distances, and order by that value descending.

EDIT

Assuming you can redesign the tables

Have 3 tables:-

Table of professionals Id Name ...

Table of qualifications Id QualificationName

LinkTable ProfessionalId QualificationId

Then do aa query that does a subselect for the levenshtein distance for the qualifications (which should mean only doing it per qualification, not per persons qualification):-

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM