You should not manipulate the column values in the MATCH()
clause of your query, as it will result in a full-table scan, defeating the purpose of a FULLTEXT
index. This is because MySQL needs to retrieve the data from each row to determine the resulting function value.
Additionally modifying the MATCH
clause is not permitted with INNODB storage tables, as the column list supplied must match exactly what is in the FULLTEXT
index.
One approach is utilizing the Generated Columns feature of MySQL, to replace the offending boolean operator characters and utilize a separate FULLTEXT
index on the generated column.
The generated column will allow your original data to remain unmodified, for use in other unrelated full-text searches and permit using the AGAINST('+5552400*')
clause without the boolean operator conflicts. The secondary column will also help reduce false positives and lower the index size that can occur by adding additional text to your source column.
The generated column will cause INSERT
and UPDATE
operations to be impacted slightly. As each row will cause an additional operation to add the second column values automatically for you.
Desired Result
| id | search_text |
| --- | --------------------- |
| 1 | called 555-2400 ext 4 |
| 2 | called 555-2400ext 4 |
Schema
CREATE TABLE table_name (
`id` INTEGER,
`search_text` VARCHAR(21),
FULLTEXT idx (search_text)
);
INSERT INTO table_name
(`id`, `search_text`)
VALUES
('1', 'called 555-2400 ext 4'),
('2', 'called 555-2400ext 4'),
('3', 'called 555-2432 ext 1'),
('4', 'called 555-2432ext 1'),
('5', 'called 444-2400 ext 2'),
('6', 'called 444-2432 ext 2');
Add Generated Column
ALTER TABLE table_name
ADD COLUMN search_text_parsed TEXT
GENERATED ALWAYS AS (REPLACE(search_text, '-', '')) STORED,
ADD FULLTEXT INDEX `idx2` (`search_text_parsed`);
You can add more boolean operators to remove as desired, by changing the generated column expression, (REPLACE(REPLACE(search_text, '-', ''), '@', ''))
Search Query
SELECT *
FROM table_name
WHERE MATCH(search_text_parsed)
AGAINST('+5552400*' IN BOOLEAN MODE);
Result
| id | search_text | search_text_parsed |
| --- | --------------------- | -------------------- |
| 1 | called 555-2400 ext 4 | called 5552400 ext 4 |
| 2 | called 555-2400ext 4 | called 5552400ext 4 |
Additionally you can automate the term value validation directly in your query, to ensure the text does not contain any of the offending boolean operators by using
REPLACE(search_text, '-', '')
SET @term='555-2400';
SELECT *
FROM table_name
WHERE MATCH(search_text_parsed)
AGAINST(CONCAT('+', REPLACE(@term, '-', ''), '*') IN BOOLEAN MODE);
Other approaches
As the question has been asked in a different manner, here is the question that closely resembles your underlying issue: How to allow fulltext searching with hyphens in the search query