I know how to get all results which contain a few words:
SELECT * FROM `table` WHERE MATCH (`row`) AGAINST ('+word1 +word2' IN BOOLEAN MODE)
But how I can all results which not contain words: "word1", "word2" ?? I need operator, something like "NOT IN". So how I can get from database everything records which not contain specific words in query using full text search?
Thanks.
You can just use NOT to negate the condition:
SELECT * FROM `table` WHERE NOT MATCH (`row`) AGAINST ('+word1 +word2' IN BOOLEAN MODE)
The MATCH condition is true on rows where it finds the words, and false where it does not find the words. Use NOT reverses the true/false result on each row.
Just like:
SELECT * FROM `table` WHERE NOT row = 'abc123'
would be true on all rows that are not the specific value 'abc123'.
Related
I'm trying to create a fulltext query that matches ANY of multiple exact phrases and excluding others. In my test query. I want to select any record that has EITHER (or both) the exact phrase 'brown cow' OR 'green cat' AND NOT 'silver rhino'. I have set up test records with combinations of these three phrases and should return 3 records if I can get my query right.
Query 1
SELECT * FROM jos_sea_messages
WHERE ((Match(body,subject) Against('"+green cat"' IN BOOLEAN MODE) OR Match(body,subject) Against('"+brown cow"' IN BOOLEAN MODE))
AND ( Match(body,subject) Against('"-silver rhino"' IN BOOLEAN MODE)))
Returns 2 records- one of them with 'silver rhino', so not what I want
Query 2
SELECT * FROM jos_sea_messages
WHERE ((Match(body,subject) Against('"+green cat" "-silver rhino"' IN BOOLEAN MODE) OR Match(body,subject) Against('"+brown cow" "-silver rhino"' IN BOOLEAN MODE)))
Returns all records with any of the phrases, including 'silver rhino', so still not right
Query 3
SELECT * FROM jos_sea_messages
WHERE (Match(body,subject) Against('"+green cat" "+brown cow" "-silver rhino"' IN BOOLEAN MODE))
Returns a whole lot of rows, some of which I don't think have any of the exact phrases?
What is the proper syntax for finding records that have either (or both) exact phrases 'brown cow' and 'green cat' but must not contain 'silver rhino'?
Thanks in advance.
I figured it out. Here is my query:
SELECT * FROM jos_sea_messages WHERE (Match(body,subject) Against('"green cat" "brown cow" -"silver rhino"' IN BOOLEAN MODE))
The + aren't required because that would mean that both phrases were needed, and the - goes outside the double quotes.
Hope it helps someone else. I'm sure this type of requirement isn't unique
I added a FULLTEXT index to a table like so:
ALTER TABLE TEST ADD FULLTEXT(name, descrip, notes);
The TEST table has 100 rows. I updated the descrip column with 'branch' in one row and 'Branches' in another row.
Then I run
SELECT * FROM TEST WHERE MATCH(name, descrip, notes) AGAINST ('branch' IN BOOLEAN MODE);
The result returned only rows that contain 'branch'. 'Branches' is not included in the result, even though it is comprised of the word that was searched. How to include 'Branches'? I want to avoid using LIKE.
In boolean mode you can use a wildcard:
AGAINST ('branch*' IN BOOLEAN MODE);
Here goes your query. You need to use wildcard.
SELECT * FROM TEST WHERE MATCH(name, descrip, notes) AGAINST ('branch*' IN BOOLEAN MODE);
I have a problem with the MATCH AGAINST query. i am getting 0 result in query when i pass onlu numeric value here is my query :
SELECT * FROM tbl1 WHERE MATCH(Sub_Name) AGAINST('+praga*' IN BOOLEAN MODE) AND MATCH(Sub_Address) AGAINST('+203*' IN BOOLEAN MODE) // result 0 row found
SELECT * FROM tbl1 WHERE MATCH(Sub_Name) AGAINST('+praga*' IN BOOLEAN MODE) AND MATCH(Sub_Address) AGAINST('+203 s*' IN BOOLEAN MODE) // result found
when i use any numeric in (203) then i get 0 result but i use any char with 203 s then result found,
and my address field value is "203 surat"
its because wildcard * IN BOOLEAN MODE returns matches that start with the word they are appended to. In your case no word starts with 203 I suppose. Hence you have to specify the word/letter which acts as a starting part of the Match. in your case 'S'
Refer The asterisk serves as the truncation (or wildcard) operator. Unlike the other operators, it should be appended to the word to be affected. Words match if they begin with the word preceding the * operator.
I am trying to enhance a third part (awesome) django framework named django-watson and I currently need to make my way through a so far unknown mysql option, the MATCH (...) AGAINST (...).
So, I already know how to retrieve an exact phrase, which is doing:
SELECT *
FROM patient_db
WHERE MATCH ( Name, id_number )
AGAINST ('"exact phrase"' IN BOOLEAN MODE);
An I also know how to retrieve results that contain words from a list:
SELECT *
FROM patient_db
WHERE MATCH ( Name, id_number )
AGAINST ('+keyword1 +keyword2' IN BOOLEAN MODE);
But I need a third option, which is mixing the two above quoted. I'd like to do something like the google search: "exact phrase" +keyword1 +keyword2.
_PS: when I search for "exact phrase" -keyword1 it works exactly as desired _
Any Ideas?
Try this.
SELECT *
FROM patient_db
WHERE MATCH ( Name, id_number )
AGAINST ('+keyword1 +keyword2' IN BOOLEAN MODE)
OR MATCH ( Name, id_number )
AGAINST ('"exact phrase"' IN BOOLEAN MODE)
I am facing difficulty in sorting the result based on field in mysql. Say for example I am searching the word "Terms" then I should get the results which starts with 'Terms' first and then 'Terms and' as next and then 'Terms and conditions' and so on.
Any one please help out who to fetch the search result based on my requirements in efficient manner using mysql query.
SELECT * FROM your_table WHERE your_column LIKE "Terms%" ORDER BY your_column;
Based on the storage engine and mysql version you probably can use the full text search capabilities of MySQL. For example:
SELECT *, MATCH (your_column) AGAINST ('Terms' IN BOOLEAN MODE) AS relevance
FROM your_table
WHERE MATCH (your_column) AGAINST ('Terms' IN BOOLEAN MODE)
ORDER BY relevance
You can find more info here: http://dev.mysql.com/doc/refman/5.5/en/fulltext-boolean.html
Or if you don't want FTS another possible solution where ordering is strictly based on the length (difference) of the strings.
SELECT * FROM your_table WHERE your_column LIKE "Terms%" ORDER BY ABS(LENGTH(your_column) - LENGTH('Terms'));
You are looking for fulltext search. Below a very simple example
SELECT id,name MATCH (name) AGAINST ('string' > 'string*' IN BOOLEAN MODE) AS score
FROM tablename WHERE MATCH (name) AGAINST ('string' > 'string*' IN BOOLEAN MODE)
ORDER BY score DESC
The advantage of this is that you can control the value of words. This is very basic, you can 'up' some matches or words (or 'down' them)
In my example an exact match ('string') would get a higher score than the string with something attached ('string*'). The following line is even one step broader:
'string' > 'string*' > '*string*'
This documentation about fulltextsearch explains allot. It's a long read, but worth it and complete.
Don't use fulltext index if you search for prefix string!
Using LIKE "Term%" the optimizer will be able to use a potential index on your_column:
SELECT * FROM your_table
WHERE your_column LIKE "Terms%"
ORDER BY CHAR_LENGTH(your_column),your_column
Note the ORDER BY clause: it first sorts by string length, and only use alphabetcal order to sort strings of equal length.
And please, use CHAR_LENGTH and not LENGTH as the first count the number of characters, whereas the later count number of bytes. Using a variable length encoding such as utf8, this would made a difference.