Mysql search for string and number using MATCH() AGAINST()
Asked Answered
C

2

13

I have a problem with the MATCH AGAINST function.

The following query give me the same result:

SELECT * FROM models MATCH(name) AGAINST('Fiat 500')
SELECT * FROM models MATCH(name) AGAINST('Fiat')

How can I search for both strings and numbers in a column of a FULL TEXT table?

Thanks

Coimbra answered 28/1, 2013 at 22:25 Comment(0)
G
40

If you need Fiat and 500 anywhere where order does not matter, then

SELECT * FROM models MATCH(name) AGAINST('+Fiat +500');

If you need Fiat 500 together, then

SELECT * FROM models MATCH(name) AGAINST('+"Fiat 500"');

If you need Fiat and zero or more 500, then

SELECT * FROM models MATCH(name) AGAINST('+Fiat 500');

If you need 500 and zero or more Fiat, then

SELECT * FROM models MATCH(name) AGAINST('Fiat +500');

Give it a Try !!!

UPDATE 2013-01-28 18:28 EDT

Here are the default settings for FULLTEXT searching

mysql> show variables like 'ft%';
+--------------------------+----------------+
| Variable_name            | Value          |
+--------------------------+----------------+
| ft_boolean_syntax        | + -><()~*:""&| |
| ft_max_word_len          | 84             |
| ft_min_word_len          | 4              |
| ft_query_expansion_limit | 20             |
| ft_stopword_file         | (built-in)     |
+--------------------------+----------------+
5 rows in set (0.00 sec)

mysql>

Notice that ft_min_word_len is 4 by default. The token 500 is length 3. thus it will not be indexed at all. You will have to do three(3) things:

STEP 01 : Configure for smaller string tokens

Add this to /etc/my.cnf

[mysqld]
ft_min_word_len = 1

STEP 02 : Restart mysql

service mysql restart

STEP 03 : Reindex all indexes in the models table

You could just drop and add the FULLTEXT index

or do it in stages and see how big it will get in advance

CREATE TABLE models_new LIKE models;
ALTER TABLE models_new DROP INDEX name;
ALTER TABLE models_new ADD FULLTEXT name (name);
ALTER TABLE models_new DISABLE KEYS;
INSERT INTO models_new SELECT * FROM models;
ALTER TABLE models_new ENABLE KEYS;
ALTER TABLE models RENAME models_old;
ALTER TABLE models_new RENAME models;

When you are satisfied this worked, then run

DROP TABLE models_old;

Give it a Try !!!

Gallagher answered 28/1, 2013 at 22:28 Comment(5)
If I search only for "500" give me no result...why?Coimbra
not trying to hijack but @Gallagher where do you place the + sign when using a php var? "+'FIAT 500'"Cp
@DannyG you got the quotes backwards. Use ('+"FAIT 500"')Gallagher
@Gallagher I have tried all of the above steps and still having issues with 2 character words. I have posted a question at #28278788Hoffarth
Is it possible to give more parameters to against() like for example: AGAINST('Fiat', 'Benz') ?Withe
B
4

Just in case it helps others, if you're using InnoDB you need to use a different set of mysql.cnf properties

eg

show variables like 'innodb_ft%';

and in my.cnf set the following value instead of ft_min_word_len

innodb_ft_min_token_size=1
Busse answered 22/2, 2018 at 2:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.