phpmysqldatabasesearch

Find record that matches most keywords in database


I have a problem to find a specific word in my database giving some keywords.

This is my database:

mydb

I would like a query which returns only the word bike from these keywords: wheels pedals chain.

I tried with this code:

SELECT * 
FROM mydb 
WHERE keywords LIKE '%wheels%' AND keywords LIKE '%pedals%' AND keywords LIKE '%chain%'

but the query doesn't give any result because the keyword "chain" doesn't exist in mydb.

I tried also this other query:

SELECT * 
FROM mydb 
WHERE keywords LIKE '%wheels%' OR keywords LIKE '%pedals%' OR keywords LIKE '%chain%' 

The query returns all the words (car, train, bike).

My scope is to try to guess a word like "bike" by searching words that define the bike, so if I insert a keyword in the search string that is not listed in the db should still come up with the result "bike". For example if I type keywords "wheels" "pedals" and a keyword that is not include in my db like "chain" it should return "bike".


Solution

  • You can do this. You just need to count how many of the keywords are matched and sort your table by that count.

    Matching one of the keywords like this: (keywords LIKE '%wheels%') will return a boolean, represented in MySQL by 1 (true) or 0 (false). So just add together all of your keyword matches like this:

    (keywords LIKE '%wheels%') + (keywords LIKE '%pedals') + (keywords LIKE '%chain%')
    

    And then sort by that sum. If you sort in descending order and select the first row, it should be the best match.

    SELECT mydb.*, 
        ((keywords LIKE '%wheels%') + 
        (keywords LIKE '%pedals') + 
        (keywords LIKE '%chain%')) AS best_match
    FROM mydb
    ORDER BY best_match DESC
    LIMIT 1;
    

    It is true that this query would be easier to write and much quicker if you had a related keywords table rather than multiple keywords in one column.