How to do fuzzy matching on a MySQL field
Hi,
For my website, I want to implement Search,ie. someone searching for "pr1nce" should get stuff like "prince". My 1st question is: how is this done? (I want a DISCUSSION, not merely links to various libs that do it already)., and 2) to make things complicated, "prince" will be inside a MySQL db. How do I do the searching? The only thing that occurred to me is to do a %LIKE% , but this won't match "pr1nce" with "prince". Is there any solution, or should I keep stuff inside a text file (hellacious). thanks for your help. |
Compute a suitable regular expression from the search strings, then use REGEXP pattern in the SQL query.
How to compute a suitable regular expression, then? Well, it depends on how complex searches you want to support. For example, I hate that Google no longer supports +"multiple words" -"multiple words" -type searches. Your users might not need that complex of a search. For a start, you could go through each search term character by character, and convert each one to a pattern. For example, characters i l 1 I L could all convert to pattern [il1IL] and so on. For security, ignore (or handle as whitespace) all characters you don't know how to convert. I do not use SQL backends for my websites -- you just need too much hardware to survive a slashdotting using one for my taste -- so I have zero idea whether this is feasible in practice or not. At minimum, you might wish to somehow limit the number of searches done per second/minute. |
This is EXACTLY the sort of post I was hoping for, thanks so much Nominal.
But... I DO have some questions, but my brain is just not working now, I'll post again in this thread, OK? :) |
I will need this as well.
Correct me if im wrong. The idee is to subtract "pr1nce" from "prince" and if its only one character or less in the result it should be listed. How would this look like in a quiery? |
What do you mean by "subtract"?
|
Quote:
In MySQL, this is done using for example Code:
WHERE field REGEXP '[pP][rR][iIl1][nN][cC][eE]' Code:
WHERE field SIMILAR TO '%[pP][rR][iIl1][nN][cC][eE]%' You do this by transforming the search terms to regular expression patterns using simple rules: each known character in the search term maps to a specific fixed string, for example 'i' to '[iI1l]' and '9' to '[9gq]'. Every unknown pattern and all whitespace you usually transform to .+ to indicate "anything but not empty". (It does make the matching less accurate, but it's usually best when the content strings may contain non-ASCII characters in other charsets.) If you use UTF-8, you can do things like map 'é' to '(E|e|É|é|È|è|Ê|ê|€)' and 'ä' to '(a|A|ä|Ä|ae|AE)' to account for transliteration and accent differences. Note that the alternate pattern format will work better than alternate characters (e.g. '[EeÉéÈèÊê€]') since each UTF-8 character may be longer than one byte; using the alternate patterns the SQL server does not need to have explicit UTF-8 support. |
Hi
The function soundex can also be used for this. It works very well as long as the language is English, and will catch a lot of spelling errors. Some examples: Code:
select soundex('prince') = soundex('pr1nce'); |
with subtract i mean character by character so prince - pr1nce would be 008000. Since its only one none zero it would be listed. Maybe its not that good as since loser - looser would not be listed.
|
All times are GMT -5. The time now is 03:41 AM. |