MariaDB has support for full-text indexing and searching:
Full-text searching is performed using MATCH() ... AGAINST syntax. MATCH() takes a comma-separated list that names the columns to be searched. AGAINST takes a string to search for, and an optional modifier that indicates what type of search to perform. The search string must be a literal string, not a variable or a column name.
MATCH (col1,col2,...) AGAINST (expr [search_modifier])
MariaDB calculates a relevance for each result, based on a number of factors, including the number of words in the index, the number of unique words in a row, the total number of words in both the index and the result, and the weight of the word. In English, 'cool' will be weighted less than 'dandy', at least at present! The relevance can be returned as part of a query simply by using the MATCH function in the field list.
IN NATURAL LANGUAGE MODE is the default type of full-text search, and the keywords can be omitted. There are no special operators, and searches consist of one or more comma-separated keywords.
Searches are returned in descending order of relevance.
Boolean search permits the use of a number of special operators:
Operator | Description |
---|---|
+ | The word is mandatory in all rows returned. |
- | The word cannot appear in any row returned. |
< | The word that follows has a lower relevance than other words, although rows containing it will still match |
> | The word that follows has a higher relevance than other words. |
() | Used to group words into subexpressions. |
~ | The word following contributes negatively to the relevance of the row (which is different to the '-' operator, which specifically excludes the word, or the '<' operator, which still causes the word to contribute positively to the relevance of the row. |
* | The wildcard, indicating zero or more characters. It can only appear at the end of a word. |
" | Anything enclosed in the double quotes is taken as a whole (so you can match phrases, for example). |
Searches are not returned in order of relevance, and nor does the 50% limit apply. Stopwords and word minimum and maximum lengths still apply as usual.
A query expansion search is a modification of a natural language search. The search string is used to perform a regular natural language search. Then, words from the most relevant rows returned by the search are added to the search string and the search is done again. The query returns the rows from the second search. The IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION or WITH QUERY EXPANSION modifier specifies a query expansion search. It can be useful when relying on implied knowledge within the data, for example that MariaDB is a database.
Creating a table, and performing a basic search:
CREATE TABLE ft_myisam(copy TEXT,FULLTEXT(copy)) ENGINE=MyISAM; INSERT INTO ft_myisam(copy) VALUES ('Once upon a time'), ('There was a wicked witch'), ('Who ate everybody up'); SELECT * FROM ft_myisam WHERE MATCH(copy) AGAINST('wicked'); +--------------------------+ | copy | +--------------------------+ | There was a wicked witch | +--------------------------+
Multiple words:
SELECT * FROM ft_myisam WHERE MATCH(copy) AGAINST('wicked,witch'); +---------------------------------+ | copy | +---------------------------------+ | There was a wicked witch | +---------------------------------+
Since 'Once' is a stopword, no result is returned:
SELECT * FROM ft_myisam WHERE MATCH(copy) AGAINST('Once'); Empty set (0.00 sec)
Inserting the word 'wicked' into more than half the rows excludes it from the results:
INSERT INTO ft_myisam(copy) VALUES ('Once upon a wicked time'), ('There was a wicked wicked witch'), ('Who ate everybody wicked up'); SELECT * FROM ft_myisam WHERE MATCH(copy) AGAINST('wicked'); Empty set (0.00 sec)
Using IN BOOLEAN MODE to overcome the 50% limitation:
SELECT * FROM ft_myisam WHERE MATCH(copy) AGAINST('wicked' IN BOOLEAN MODE); +---------------------------------+ | copy | +---------------------------------+ | There was a wicked witch | | Once upon a wicked time | | There was a wicked wicked witch | | Who ate everybody wicked up | +---------------------------------+
Returning the relevance:
SELECT copy,MATCH(copy) AGAINST('witch') AS relevance FROM ft_myisam WHERE MATCH(copy) AGAINST('witch'); +---------------------------------+--------------------+ | copy | relevance | +---------------------------------+--------------------+ | There was a wicked witch | 0.6775632500648499 | | There was a wicked wicked witch | 0.5031757950782776 | +---------------------------------+--------------------+
WITH QUERY EXPANSION. In the following example, 'MariaDB' is always associated with the word 'database', so it is returned when query expansion is used, even though not explicitly requested.
CREATE TABLE ft2(copy TEXT,FULLTEXT(copy)) ENGINE=MyISAM; INSERT INTO ft2(copy) VALUES ('MySQL vs MariaDB database'), ('Oracle vs MariaDB database'), ('PostgreSQL vs MariaDB database'), ('MariaDB overview'), ('Foreign keys'), ('Primary keys'), ('Indexes'), ('Transactions'), ('Triggers'); SELECT * FROM ft2 WHERE MATCH(copy) AGAINST('database'); +--------------------------------+ | copy | +--------------------------------+ | MySQL vs MariaDB database | | Oracle vs MariaDB database | | PostgreSQL vs MariaDB database | +--------------------------------+ 3 rows in set (0.00 sec) SELECT * FROM ft2 WHERE MATCH(copy) AGAINST('database' WITH QUERY EXPANSION); +--------------------------------+ | copy | +--------------------------------+ | MySQL vs MariaDB database | | Oracle vs MariaDB database | | PostgreSQL vs MariaDB database | | MariaDB overview | +--------------------------------+ 4 rows in set (0.00 sec)
Partial word matching with IN BOOLEAN MODE:
SELECT * FROM ft2 WHERE MATCH(copy) AGAINST('Maria*' IN BOOLEAN MODE); +--------------------------------+ | copy | +--------------------------------+ | MySQL vs MariaDB database | | Oracle vs MariaDB database | | PostgreSQL vs MariaDB database | | MariaDB overview | +--------------------------------+
Using boolean operators
SELECT * FROM ft2 WHERE MATCH(copy) AGAINST('+MariaDB -database' IN BOOLEAN MODE); +------------------+ | copy | +------------------+ | MariaDB overview | +------------------+
© 2019 MariaDB
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.
https://mariadb.com/kb/en/fulltext-index-overview/