MySQL: Use plus sign together with wildcard in fulltext search - mysql

I've tried the following query without any success; the initial wildcard for every word is for some reason ignored.
SELECT * FROM table WHERE MATCH(field) AGAINST("+*foo* +*bar*" IN BOOLEAN MODE)
I've also tried to use brackets, but with no different result:
SELECT * FROM table WHERE MATCH(field) AGAINST("+(*foo*) +(*bar*)" IN BOOLEAN MODE)
Shouldn't any of these work?

Mysql fulltext indexes support only searching for prefixes. So you can search for "foo*" but not "*foo*"
More information

Related

MySQL - Match Against not search on single string [duplicate]

I understand that the asterisk is a wildcard that can be appended to the end of fulltext search words, but what if my searched keyword is a suffix? For example, I want to be able to search for "ames" and have a result that contains the name "james" returned. Here is my current query which does not work because you cannot prepend asterisks to fulltext searches.
SELECT * FROM table WHERE MATCH(name, about, address) AGAINST ("*$key*" IN BOOLEAN MODE)
I would simply switch to using LIKE, but it would be way too slow for the size of my database.
What you could do is create another column in your database with full-text search index, this new column should have the reversed string of the column you are trying to search on, and you will reverse the search query and use it to search on the reversed column, here is how the query will look like:
SELECT * FROM table WHERE MATCH(column1) AGAINST ("$key*" IN BOOLEAN MODE) OR MATCH(reversedColumn1) AGAINST ("$reveresedkey*" IN BOOLEAN MODE)
the first condition
MATCH(column1) AGAINST ("$key*" IN BOOLEAN MODE)
example:
reversedColumn1==>Jmaes $reveresedkey*==>ames*
will search for words that start with ames ==> no match
the seconds condition
MATCH(reversedColumn1) AGAINST ("$reveresedkey*" IN BOOLEAN MODE)
example:
reversedColumn1==>semaJ $reveresedkey*==>sema*
will search for words that end with ames ==> we have a match
This might not be a bad idea if your text is short:
Can't be done due to limitation of MySQL. Values are indexed left-to-right, not right-to-left. You'll have to stick with LIKE if you want wildcards prepended to search string.

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 )

Prepending an * (asterisk) to a Fulltext Search in MySQL

I understand that the asterisk is a wildcard that can be appended to the end of fulltext search words, but what if my searched keyword is a suffix? For example, I want to be able to search for "ames" and have a result that contains the name "james" returned. Here is my current query which does not work because you cannot prepend asterisks to fulltext searches.
SELECT * FROM table WHERE MATCH(name, about, address) AGAINST ("*$key*" IN BOOLEAN MODE)
I would simply switch to using LIKE, but it would be way too slow for the size of my database.
What you could do is create another column in your database with full-text search index, this new column should have the reversed string of the column you are trying to search on, and you will reverse the search query and use it to search on the reversed column, here is how the query will look like:
SELECT * FROM table WHERE MATCH(column1) AGAINST ("$key*" IN BOOLEAN MODE) OR MATCH(reversedColumn1) AGAINST ("$reveresedkey*" IN BOOLEAN MODE)
the first condition
MATCH(column1) AGAINST ("$key*" IN BOOLEAN MODE)
example:
reversedColumn1==>Jmaes $reveresedkey*==>ames*
will search for words that start with ames ==> no match
the seconds condition
MATCH(reversedColumn1) AGAINST ("$reveresedkey*" IN BOOLEAN MODE)
example:
reversedColumn1==>semaJ $reveresedkey*==>sema*
will search for words that end with ames ==> we have a match
This might not be a bad idea if your text is short:
Can't be done due to limitation of MySQL. Values are indexed left-to-right, not right-to-left. You'll have to stick with LIKE if you want wildcards prepended to search string.

Boolean search with truncated exclutions words don't work for me

When I search for:
SELECT * FROM db.test
WHERE
MATCH(story)AGAINST('(+bananas -banana*)'IN BOOLEAN MODE)
I get rows returned but when I search for
SELECT * FROM db.test
WHERE
MATCH(story)AGAINST('(+bananas -bananas)'IN BOOLEAN MODE)
or
SELECT * FROM db.test
WHERE
MATCH(story)AGAINST('(+bananas -bananas*)'IN BOOLEAN MODE)
I get no result. To me it seems like you canĀ“t use * together with the minus sign.
Does anybody know if thats the case or if its a setting in MySql.
Kind regards
Olle
The table is MYISAM and I have a index on the column story.
The last 2 queries do not give any result because they contain contradicting conditions - story must have the word "bananas" and must not have the word "bananas". This is not possible and hence no results.
However the first query means that "bananas" must be present but no "banana".
Also, you may use * with the minus operator.
Hope this helps.
The solution is to skip the parentheses. If I search for '+bananas -banana*' instead of '(+bananas -banana*)' it works. It took a while to figure out thou.
Cheers

Mysql fulltext boolean ignore phrase

I'm trying to come up with a mysql boolean search that matches "monkey" but ignores / doesn't take into account an matches of "monkey business".
Something like the following is the general idea but it negates the value. I need it to not match rows with "monkey business" unless they also have "monkey" without "business" after it elsewhere in the text.
SELECT * FROM table
MATCH (title) against ('+monkey ~"monkey business"' IN BOOLEAN MODE);
Is it possible? Thanks in advance for any help you can give! I realise this could be done with better search engines, at the moment fulltext is all I can use.
I tested this and it works:
SELECT * FROM table
WHERE MATCH (title) against ('+monkey' IN BOOLEAN MODE)
AND NOT MATCH (title) against ('+"monkey business"' IN BOOLEAN MODE);
p.s I also tried the boolean negation operator:
AND MATCH (title) against ('-"monkey business"' IN BOOLEAN MODE)
but it didn't work.