Why is Mysql match boolean mode not finding "Knows" - mysql

I have these two queries
SELECT * FROM `foo` WHERE MATCH(`title`) AGAINST('knows' in boolean mode )
SELECT * FROM `foo` WHERE MATCH(`title`) AGAINST('woman' in boolean mode )
and in the table I have a row with title = "a woman knows"
the first query finds that row, but the second doesn't!
I have experimented with different alternatives - for example, if the title contains "a woman knots" then querying for a match against "knots" works
I am mystified, so any help you can provide would be welcome.

"knows" is a stopword and will not be indexed (and therefore ignored in all searches).
You can load your own list of stopwords with the ft_stopword_file server option.

Related

match against doesn't work with the word "when"

When desc contains the string: zoom when wifi dies for 1 second
Query 1:
SELECT * FROM `pics` WHERE MATCH(title, desc, owntags, usertags) AGAINST('+zoom* +wifi*' IN BOOLEAN MODE)
No problem, I get the row!
Query 2:
SELECT * FROM `pics` WHERE MATCH(title, desc, owntags, usertags) AGAINST('+zoom* +when*' IN BOOLEAN MODE)
No results! So when belongs to sql commands.
So how to solve this?
You need to learn some basics about full text search. One very important concept are stop words. These are words that are not included in the full-text index, because they are so common or add little meaning (at least from the perspective of the person who created the stop word list . . . a famous problem involves the band The Who).
The word 'when' is a common stop word and a default stop word in MySQL (see here and here). So, it is not being indexed.
You will need to recreate your full text indexes, either removing all stop words or using your own custom list.

Cannot change InnoDB full text minimum word length

I have a MySQL 5.7.31 InnoDB table with full text index enabled...
if I search for a longer word, I get results:
SELECT * FROM my_table WHERE match(my_title) against('landscape in' IN BOOLEAN MODE)
if I search full text for short word (e.g in), I get no results
SELECT * FROM my_table WHERE match(my_title) against('in' IN BOOLEAN MODE)
the data is there, I can find it with like %% query:
SELECT * FROM my_table WHERE my_title LIKE '%in%'
I set these two in /etc/my.cnf, I understand one is for InnoDB and one for MyIsam, I restarted MySQL, I still cannot run the above short full text query.
ft_min_word_len=1
innodb_ft_min_token_size=1
Edit:
If I have a value like landscape in Paris, then I get data for against('+landscape +Paris' IN BOOLEAN MODE) but NOT for against('+landscape +in +Paris' IN BOOLEAN MODE)
Is in a reserved word maybe ?
"in" is probably in the "stop list". Change the specification of the stoplist file.
After changing the min-len or the stoplist, you must rebuild the Fulltext index(es). (Restarting MySQL is not needed.)
An alternative I used on one situation: I added + to long words. For example, against('+landscape in +Paris' IN BOOLEAN MODE) would probably achieve your goal without changing either the min-len or the stopword list.
(Yes, there are several 'differences' between MyISAM and InnoDB. I have not found a definitive list in the docs. Here's my attempt at such a list: http://mysql.rjweb.org/doc.php/myisam2innodb#fulltext )

*Actual* exact MySQL fulltext search

So I'm having some difficulty creating exact searches in MySQL fulltext.
In my database, I'm trying to find jobs with a specific keyword in its title.
So I might try
WHERE MATCH(jobTitle) AGAINST ('"fs sales"' IN BOOLEAN MODE)
However, this finds matches on "sales", not "fs sales"
How can I ensure that "fs sales" matches EXACTLY on "fs sales" and not "sales"?
Table is InnoDB for reference.
"fs" is probably excluded from the search as too short.
Check the value of innodb_ft_min_token_size and manual: https://dev.mysql.com/doc/refman/5.6/en/fulltext-fine-tuning.html
You have to rebuild the index after changing that variable.
Your query should work. My guess, though is that you did not change the minimum word length, so "fs" was never indexed. See here for information on this.
Other possibilities are that there are other characters in the text, perhaps characters you do not see.
You might try this
select t.*
from (select . . .
WHERE MATCH(jobTitle) AGAINST ('+fs +sales' IN BOOLEAN MODE)
) t
where jobTitle like '%fs sales%';
This only does the like on the returned set from the match.
However, my best guess is that innodb_ft_min_token_size is set to its default value of 3, so "fs" is not being indexed.
you can do it like
select col1, col2 from table_name where text_column like '%fs sales%'
this will return all the records having fs sales in them..

match against not making sense

This is my filter text:
Oliver used book
If I search for 'Oliver' it works, if I search for 'book' it works but if I search for 'used' it does not work.
Heater white fan HEOP1322
Heater -> works : white -> works : fan -> does not work : HEOP -> does not work : HEOP1322 -> works.
My query is like this:
SELECT * FROM table WHERE MATCH(filter) AGAINST ('fan' IN BOOLEAN MODE)
SELECT * FROM table WHERE MATCH(filter) AGAINST ('HEOP' IN BOOLEAN MODE)
SELECT * FROM table WHERE MATCH(filter) AGAINST ('used' IN BOOLEAN MODE)
Why d'hell does the word used not work and the word book works? They have the same length.
I also tried this suggestions Mysql search for string and number using MATCH() AGAINST() without success.
Edit: Solved, follow this instructions.
XAMPP MySQL - Setting ft_min_word_len
"used" is one of the default MySQL full text stopwords: https://dev.mysql.com/doc/refman/5.1/en/fulltext-stopwords.html. Stopwords are words which are ignored because they are too frequent in the (English) language and would not positively contribute to the result of a full text search. If you're only querying for single words, a LIKE %..% query may be more suited than a full-blown full text search.

mysql fulltext boolean search with asterix

I have a query like below:
SELECT prd_id FROM products WHERE MATCH (prd_search_field)
AGAINST ('+gul* +yetistiren* +adam*' in boolean mode);
This doesn't return the rows including 'gul'.
http://dev.mysql.com/doc/refman/5.0/en/fulltext-boolean.html
The document says this.
Then a search for '+word +the*' will likely return fewer rows than a
search for '+word +the':
The former query remains as is and requires both word and the* (a word starting with the) to be present in the document.
The latter query is transformed to +word (requiring only word to be present). the is both too short and a stopword, and either condition is enough to cause it to be ignored.
So as I understood the too short word condition must not be applied in my situation since I use * after each word. What's wrong with this?
As a solution I use the below query but since it's slow, I need to find another solution. Any idea would be appreciated? Thanks in advance..
SELECT prd_id FROM products WHERE 1 AND MATCH (prd_search_field)
AGAINST ('+yetistiren* +adam*' in boolean mode) AND prd_search_field
LIKE '%gul%';
As a note ft_min_word_length=4 as default in all shared hosting environments, and I cannot change it.