I am doing a search function in php, and I am allowing BOOLEAN search, but when I enter text containing chars like #, the query fails.
For example, when I search for #everyone, it throws an error.
I tried to solve this by adding doublequotes, but it doesn't work as expected, since for the search #everyone, it works but returns rows containing everyone and #everone.
I would like to know how we can search for words containing special chars in mysql full text search
Here's my query (simplified) :
SELECT * FROM messages WHERE MATCH(body) AGAINST ('#everyone' IN BOOLEAN MODE)
By default, MySQL does not treat '#' as a valid character for a word. If you want to treat '#' it, then review the documentation on the subject.
After you have made the changes, then you will need to re-build your index.
Related
I'm creating a paraphrasing system, where a user inputs text and the system paraphrases for them.
My database looks like this:
KeyWord: dainty
Synonyms1: choice; delicious; tasty; juicy; luscious; palatable; savoury
Synonyms2: ethereal; beautiful; fragile; charming; petite; frail; elegant
where Keyword (varchar), Synonym1 (text), and Synomy2 (text) are database columns. The example above is one row of a database with 3 fields and their values.
This how it works if the system finds, for example, a word like tasty, it can be replaced by any of the words separated by a semicolon from either Synomyn1 or Synonym2 or the keyword because they are all synonyms.
Let me explain how the word search is working. The system first searches for the word in the Keyword column, if the word is not found, I go further and search for a word in the Synmon1 column and so on.
My Problem is checking the user's specific word in the Synonym1 or Synonym2 columns. When I use the LIKE clause, the generic way of searching from the database, the system is not searching for a full name, instead, it's searching for characters. For example, let's assume the writer's text is: "Benson has an ice cube", the system is assuming the ice was found in the choice. I don't want that, I want to search for a full word.
If anyone has understood me, please help to solve this.
If I understand your question, you want to search for ice in columns Synonyms1 and Synonyms2 but make sure you do not inadvertently match a word such as choice.
If you have ever read or heard anything on the subject of database normalization you would realize that your database does not even meet the requirements for 1NF (first normal form) becuase it has columns that consist of repeating values, which, as you have found out, makes searching inefficient and difficult. But let's move on:
A synonym column might just contain one word, so it might look like:
ethereal
Or:
ethereal; beautiful; fragile; charming; petite; frail; elegant
Thus the word you are looking for might be:
the entire column value
preceded by nothing and followed by a ;
preceded by a space and followed by a ;
preceded by a space and followed by nothing
So if your version of MySQL does not support regular expressions, then if you are looking for example the word ice in column Synonyms2, the WHERE clause should be:
WHERE (
Synonyms2 = 'ice'
OR
Synonyms2 like 'ice;%'
OR
Synonyms2 like '% ice;%'
OR
Synonyms2 like '% ice'
)
If you are running SQL 8+, then:
WHERE regexp_like(Synonyms2, '( |^)ice(;|$)')
This states that ice must be preceded by either a space or start of string and followd by either a ; or end of string.
This may be a newbie question, as I'm not an expert in SQL. However, couldn't find the answer using Google.
I have a table called record_fields which contains the majority of my system's content, which I want to search in. The content cell is defined as LONGTEXT as it can include extremely long input.
Originally, I used (simplifying the query a bit for clarity sake):
SELECT * FROM record_fields WHERE LOWER(content) LIKE LOWER('%{$keyword}%')
Execution time aside, this query has one major issue. If I search for the term "post" it will return all content which has words like "poster", "posting" and others. I wanted to add a FULLTEXT search.
Now the query looks like this (again, simplified):
SELECT * FROM record_fields WHERE MATCH (content) AGAINST ('{$keyword}')
However, this is still problematic. With MATCH, if my system's users search for the words "Bank of America", for example, all records that either have the word "Bank" and "America" will be returned.
TL;DR - my question is this:
how do I use MATCH to search for exact phrases with space in them?
Any help would be highly appreciated, thanks in advance!
%{keyword}% matches all text sub-strings that include your keyword anywhere in the string. MATCH usually takes all keywords in the match string as individual search terms, and matches against each. You can use boolean mode and use a + symbol before each required keyword. Take a look at the MySQL reference for this.
Edited the answer to reflect Idan's response in not getting the results from the suggested %keyword solution.
You can use Match Against With Boolean Mode and you can put your input string inside '"{$keyword}"'.
Check last example in below link
https://dev.mysql.com/doc/refman/5.5/en/fulltext-boolean.html
SELECT * FROM record_fields WHERE MATCH (content) AGAINST ('"{$keyword}"' IN BOOLEAN MODE )
I have following match against query which searches records from database table based on search phrase.
SELECT * FROM My_Table WHERE MATCH (catchall) AGAINST ('"horse"' IN BOOLEAN MODE)
This query works properly. When search phrase contains special characters like '(' etc It just skips such special characters.
If i search for "(horse)" it gives me same result as it gives for "horse".
SELECT * FROM My_Table WHERE MATCH (catchall) AGAINST ('"(horse)"' IN BOOLEAN MODE)
Does it mean match against query doesn't work with special characters or am i missing something. Please suggest. Thanks.
I tried by removing IN BOOLEAN MODE from the query but it didn't work.
from the documentation:
Parentheses group words into subexpressions. Parenthesized groups can be nested.
if you want to treat prenthes as "word chars", there are two possibilitys:
If you want to change the set of characters that are considered word
characters, you can do so in two ways. Suppose that you want to treat
the hyphen character ('-') as a word character. Use either of these
methods:
Modify the MySQL source: In myisam/ftdefs.h, see the true_word_char()
and misc_word_char() macros. Add '-' to one of those macros and
recompile MySQL.
Modify a character set file: This requires no recompilation. The
true_word_char() macro uses a “character type” table to distinguish
letters and numbers from other characters. . You can edit the
contents in one of the character set XML files to specify
that '-' is a “letter.” Then use the given character set for your
FULLTEXT indexes.
After making the modification, you must rebuild the indexes for each
table that contains any FULLTEXT indexes.
a third way would be to not use MATCH ... AGAINST at all and use LIKE instead - but this might get complicated (if you want to use the other operators of ful-text-searches such as +/-) and slow down your query.
I am using mysql match against query in my search query like this way
MATCH(film_name) AGAINST ('the vacation' IN BOOLEAN MODE).
But previously i use this one
film_name like '%the vacation%'
So my question is that i am getting the right result now by using match and against but the problem is that when i am using like there i can use the % sign before and after the search string so if the search string present with in the string then it was return the result so plz tell how to write my " MATCH(film_name) AGAINST ('the vacation' IN BOOLEAN MODE) " so that it also behaves `like '%'.
If the file name is 'rocketsingh'
then if i run film_name like '%rocket%' then it shows me the result
but if i run MATCH(film_name) AGAINST ('rocket' IN BOOLEAN MODE) then it will not show any result. Please suggest what to do.
MATCH command allows only prefixed wildcards but not postfixed wilcards. Since single words are indexed, a postfix wildcard is impossible to manage in the usual way index does. You can't retrieve *vacation instantly from index because left characters are the most important part of index.
The answer is: You can't. The MATCH AGAINST operator matches words, not strings. There is a difference between the two. Also note that your example will also match vacation, the, vacation the or the something something vacation and other. You should read here what searches you can do.
You should stick to your first option with LIKE if you don't want word searches.
I have a search engine in PHP. When a search normally it's OK. Search text is 'company', and in the database there is 'company' in the field...
The problem is when the search text is &company or -company and the data is &company or -company there is no match. why?
problem with the - and & string...
Try putting your search terms in quotes. This should help mysql know you mean those characters literally in fulltext search:
SELECT * FROM tablename MATCH (company) AGAINST ('"&company"' IN BOOLEAN MODE)
SELECT * FROM tablename MATCH (company) AGAINST ('"-company"' IN BOOLEAN MODE)
If you are using FullText Search then the & and - are reserved characters. I could not find any nice solution to this problem. What I did is just remove the special character and run the full text search. For example if they are looking for At&t I run a search for "AT" "T", but if you have noise words At and A are in there and you will not get any results.
Another solution is to detect when they are requesting a special character and run a LIKE '%&Company%' search instead of a full text search, but this will affect the performance of the query.