ignoring mysql fulltext stopwords in query - mysql

I'm building a search for a site, which utilizes a fulltext search. The search itself works great, that's not my problem. I string together user provided keywords (MATCH... AGAINST...) with AND's so that multiple words further narrow the results. Now, I know that certain stop words aren't indexed, and that's fine with me I don't really want to use them as selection criteria. But, if a stopword is provided in the keyword set (by the user), it kills all the results (as expected) even if the word actually is in a certain text block.
My question: is there any way to check to see if a certain word is a stop word at the time of the query? My preferred solution would just be to exclude the relevant word from the search criteria (I don't care if a user can narrow results by the word 'neither', I just don't want MySQL to return an empty result set because the user provided it, even though neither does exist in the results). Or, am I just going to have to empty the stopword list? Thanks very much for any help.
edit ----
I'm sorry, but there's really no code snippets to provide for this one. The code works fine, actually exactly as expected. It's more of a logical problem I'm dealing with. But as an example, in the way of explanation:
lets say there are three records, which include the words (but are not limited to)
1: apple, orange, mango, banana
2: grape, orange, pineapple, mango
3: potato, mango, melon, keira knightly
If the search word entered by the user is mango, all results are returned correctly. If the words are orange AND mango, results 1 and 2 are returned (correctly). Now, let's say banana is a stop word (it's not... but let's assume it is), if the search is for orange, mango, AND banana, no results are returned (because banana isn't in the fulltext index).
What I'm looking for is if anyone else has encountered this problem, and has a way to work around it. Sort of an:
if 'banana' NOT STOP WORD match 'banana' against `words`. (OBVIOUSLY not real code).
Or... am I just going to have to drop the stopword list...

You can verify the keywords by comparing all stopwords. Here is the list of stopwords
I've found out a solution to disable stopwords from fulltext.
You just need to locate .cnf file and add this,
ft_stopword_file = ""
restart mysql engine and rebuild indexes;
Hope this work

How to disable fulltext stopwords in MySQL:
In my.ini text file (MySQL) :
ft_stopword_file = "" or link an empty file "empty_stopwords.txt"
ft_min_word_len = 2
// set your minimum length, but be aware that shorter words (3,2) will increase the query time dramatically, especially if the fulltext indexed column fields are large.
Save the file, restart the server.
The next step should be to repair the indexes with this query:
REPAIR TABLE tbl_name QUICK.
However, this will not work if you table is using InnoDB storage engine. You will have to change it to MyISAM :
ALTER TABLE t1 ENGINE = MyISAM;
So, once again:
1. Edit my.ini file and save
2. Restart your server (this cannot be done dynamically)
3. Change the table engine (if needed) ALTER TABLE tbl_name ENGINE = MyISAM;
4. Perform repair REPAIR TABLE tbl_name QUICK.
Be aware that InnoDB and MyISAM have their speed differences. One read faster, other writes faster ( read more about that on the internet )

disable stopword for fulltext search in mysql using this steps
1: open my.ini file in mysql
2: place below two line after [mysqld] line in my.ini (search [mysqld] in file)
ft_min_word_len=1
ft_stopword_file=""
3: restart your server
4: repair your table using below command
> repair table tablename;
5: now your search is working....

For the INNODB case, it is possible to disable stop_words when you create the index.
SET ##SESSION.innodb_ft_enable_stopword = 'OFF';
create table foo
....
fulltext (search_col)
This will cause the full text index to be created with the stopwords disabled. You can verify by using the following queries.
SET GLOBAL innodb_ft_aux_table = 'schema/foo';
select * from information_schema.innodb_ft_config;
Your results will look like this:
Notice that use_stopword is set to 0.
Search for use_stopwords on this mysql documentation page.
and Checkout innodb_ft_enable_stopword here

setting
ft_stopword_file = ""
didn't work for me, I'm using INNODB tables and MySQL 5.6 (stop words still not indexed in full text indexes after optimizing associated table)
this solution works (even if you are not super user) :
CREATE TABLE mydb.stopwordslist(value VARCHAR(20)) ENGINE = INNODB;
INSERT INTO mydb.stopwordslist(value) VALUES ('skipthisword');
for all users but you still need super user rights :
SET GLOBAL innodb_ft_server_stopword_table = 'mydb/stopwordslist';
for just the user (assuming it the one who recreating indexes and updating columns)
SET SESSION innodb_ft_user_stopword_table = 'mydb/stopwordslist';
as it is a session variable, it won't last when your session is closed so please make sure you set it at each session or before you optimize or insert into tables having fulltext index or when you update column indexed by fulltext index

try using MATCH…AGAINST…IN BOOLEAN MODE
Like this one:
WHERE MATCH(author,title)
AGAINST('"origin of"' IN BOOLEAN MODE);

Related

Disable MySQL fulltext search stopwords in innodb

I am using a FullText index on MySQL v5.6 InnoDB table.
and running this query to perform search on the table
SELECT * FROM `table` WHERE MATCH(title,desc) AGAINST ('+hello -for' IN BOOLEAN MODE);
when i run the above query it still gives me the results which includes word for in the title or desc.
I have already made the following changes in my my.cnf file to avoid stopwords.
innodb_ft_min_token_size=2
ft_min_word_len=2
ft_stopword_file = ""
Why i am still getting results with word for included in it?
You need to ensure that the server variable innodb_ft_enable_stopword is set to OFF if you aren't wanting to use stop words at all.
SET ##SESSION.innodb_ft_enable_stopword = 'OFF';

MySql Fulltext search using 2 character word

I've set ft_min_word_len = 1 and running show variables like 'ft%'; also shows the same.
Also have already updated the Fulltext indexes by dropping and re-creating them.
But when I run SELECT OriginalProductName FROM products WHERE MATCH (ProductName) AGAINST ('+samsung +tv' IN BOOLEAN MODE); against a row which is having "Samsung Hg55nc890xf 3d 1080p Led lcd Tv Hdtv" as value it returns 0 results.
It works as expected when I execute SELECT OriginalProductName FROM products WHERE MATCH (ProductName) AGAINST ('+samsung +led' IN BOOLEAN MODE);
I am using MySQL 5.6.22. Innodb is the Table engine.
How can make MySql Fulltext search to search 2 character words like tv, 32, US etc...?
I found that this issue was specific to innodb storage engine. I've solved the issue by adding
[mysqld]
innodb_ft_min_token_size =2; to /etc/my.cnf

match.. against

My query is not working, it always show related 0. Even against data do exist.
SELECT number, MATCH(number)
AGAINST('02' '01' '03' WITH QUERY EXPANSION)
as related FROM lottery_entries;
you can see the result below.
i don't know what is the reason.
It is because MySQL has a server parameter - The minimum length of the word to be included in a FULLTEXT index. Default value for this parameter is 4 so your words like 'XX' are not included in this index. You should change this system parameter, restart server and then rebuild all FULLTEXT indexes.
REPAIR TABLE lottery_entries QUICK;
Change the full text index minimum word length with MySQL

Full text search with a very simple MySQL statement

I recently came across a wierd issue with MySQL Fulltext search. My statement is really simple:
SELECT * FROM `mytable` WHERE MATCH (`desc`) AGAINST ('+NOR +710' IN BOOLEAN MODE)
And this is what in the desc column: "The NOR 710 also has smoke seal ..."
For some reason it won't find that row. I added Fulltext index to that column, mysql version is 5.1.56 , database engine of that table is MyISAM. Is there anything else i need to check?
Thanks
By default, fulltext indexes will ignore words that are shorter than 4 charaters. Adjust your ft_min_word_len to also include the shorter words.

ft_min_word_len set in local my.cnf?

Is it possible to set ft_min_word_len for a certain user (such as by placing a my.cnf file in the user home dir with ft_min_word_len set)? The documentation says I need to restart the server after making this change, but a user does not have access to do that.
I'm working with this now, so to add as a reference for anyone looking at this...
You can use this query in a query
browser or the MySQL prompt to show
the state of ft_min_word_len: "SHOW
VARIABLES LIKE 'ft_min_word_len';"
ft_min_word_len deafults to a value
of '4' and is not by default listed
in "my.cnf". To change it's default
value, add: "ft_min_word_len = 3" to
my.cnf under the [mysqld] section.
After changing the value of
ft_min_word_len, the server must be
restarted.
After changing the value of
ft_min_word_len, any indexes you have
must be rebuilt
A fast way to rebuild an index is to
use this query: "REPAIR TABLE
your_table_name QUICK;" Note:
You're using the name of the table
only, not the name of any indexes.
If you have more than one index
against the 'your_table_name' table,
all of them will be re-built.
No, it's not possible, because it changes how the fulltext indices are built. It takes effect at index generation, not (only) at query time.
FYI: Not only do you have to restart the server, you have to rebuild all your fulltext indices after changing it.