[mysql] 13.9 Full-Text 搜索函数
1 | [MATCH (col1,col2,...) AGAINST (expr [search_modifier])] |
MySQL has support for full-text indexing and searching:
-
A full-text index in MySQL is an index of type FULLTEXT
.
-
Full-text indexes can be used only with InnoDB
or MyISAM
tables, and can be created only for CHAR
, VARCHAR
, or TEXT
columns.
-
As of MySQL 5.7.6, MySQL
provides a built-in full-text ngram parser that supports Chinese, Japanese, and Korean (CJK), and an installable MeCab full-text parser plugin for Japanese. Parsing differences are outlined in “ngram Full-Text Parser” and “MeCab Full-Text Parser Plugin”
-
A FULLTEXT
index definition can be given in the CREATE TABLE
statement when a table is created, or added later using ALTER TABLE
or CREATE INDEX
.
-
For large data sets, it is much faster to load your data into a table that has no FULLTEXT
index and then create the index after that, than to load data into a table that has an existing FULLTEXT
index.
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 string value that is constant during query evaluation. This rules out, for example, a table column because that can differ for each row.
There are three types of full-text searches:
-
A natural language search interprets the search string as a phrase in natural human language (a phrase in free text). There are no special operators. The stopword list applies. For more information about stopword lists, see[Section 13.9.4, “Full-Text Stopwords”].
Full-text searches are natural language searches if the IN NATURAL LANGUAGE MODE
modifier is given or if no modifier is given. For more information, see [Section 13.9.1, “Natural Language Full-Text Searches”].
-
A boolean search interprets the search string using the rules of a special query language. The string contains the words to search for. It can also contain operators that specify requirements such that a word must be present or absent in matching rows, or that it should be weighted higher or lower than usual. Certain common words (stopwords) are omitted from the search index and do not match if present in the search string. The IN BOOLEAN MODE
modifier specifies a boolean search. For more information, see [Section 13.9.2, “Boolean Full-Text Searches”].
-
A query expansion search is a modification of a natural language search. The search string is used to perform a 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. For more information, see [Section 13.9.3, “Full-Text Searches with Query Expansion”].
For information about FULLTEXT
query performance, see [Section 9.3.4, “Column Indexes”].
For more information about InnoDB
FULLTEXT
indexes, see [Section 15.8.10, “InnoDB FULLTEXT Indexes”].
Constraints on full-text searching are listed in [Section 13.9.5, “Full-Text Restrictions”].
The [myisam_ftdump] utility dumps the contents of a MyISAM
full-text index. This may be helpful for debugging full-text queries. See [Section 5.6.2, “myisam_ftdump — Display Full-Text Index information”].
1. 自然语言全文搜索
By default or with the IN NATURAL LANGUAGE MODE
modifier, the MATCH()
function performs a natural language search for a string against a text collection. A collection is a set of one or more columns included in a FULLTEXT
index. The search string is given as the argument to AGAINST()
. For each row in the table, MATCH()
returns a relevance value; that is, a similarity measure between the search string and the text in that row in the columns named in the MATCH()
list.
1 | mysql> CREATE TABLE articles ( |
By default, the search is performed in case-insensitive fashion. To perform a case-sensitive full-text search, use a binary collation for the indexed columns. For example, a column that uses the latin1
character set of can be assigned a collation of latin1_bin
to make it case sensitive for full-text searches.
When MATCH()
is used in a WHERE
clause, as in the example shown earlier, the rows returned are automatically sorted with the highest relevance first. Relevance values are nonnegative floating-point numbers. Zero relevance means no similarity. Relevance is computed based on the number of words in the row (document), the number of unique words in the row, the total number of words in the collection, and the number of rows that contain a particular word.
Note
The term “document” may be used interchangeably with the term “row”, and both terms refer to the indexed part of the row. The term “collection” refers to the indexed columns and encompasses all rows.
To simply count matches, you could use a query like this:
1 | mysql> SELECT COUNT(*) FROM articles |
You might find it quicker to rewrite the query as follows:
1 | mysql> SELECT |
The first query does some extra work (sorting the results by relevance) but also can use an index lookup based on the WHERE
clause. The index lookup might make the first query faster if the search matches few rows. The second query performs a full table scan, which might be faster than the index lookup if the search term was present in most rows.
For natural-language full-text searches, the columns named in the MATCH()
function must be the same columns included in some FULLTEXT
index in your table. For the preceding query, note that the columns named in the MATCH()
function (title
and body
) are the same as those named in the definition of the article
table’s FULLTEXT
index. To search the title
or body
separately, you would create separate FULLTEXT
indexes for each column.
You can also perform a boolean search or a search with query expansion. These search types are described in[Section 13.9.2, “Boolean Full-Text Searches”], and [Section 13.9.3, “Full-Text Searches with Query Expansion”].
A full-text search that uses an index can name columns only from a single table in the MATCH()
clause because an index cannot span multiple tables. For MyISAM
tables, a boolean search can be done in the absence of an index (albeit more slowly), in which case it is possible to name columns from multiple tables.
The preceding example is a basic illustration that shows how to use the MATCH()
function where rows are returned in order of decreasing relevance. The next example shows how to retrieve the relevance values explicitly. Returned rows are not ordered because the SELECT
statement includes neither WHERE
nor ORDER BY
clauses:
1 | mysql> SELECT id, MATCH (title,body) |
The following example is more complex. The query returns the relevance values and it also sorts the rows in order of decreasing relevance. To achieve this result, specify MATCH()
twice: once in the SELECT
list and once in theWHERE
clause. This causes no additional overhead, because the MySQL optimizer notices that the two MATCH()
calls are identical and invokes the full-text search code only once.
1 | mysql> SELECT id, body, MATCH (title,body) AGAINST |
The MySQL FULLTEXT
implementation regards any sequence of true word characters (letters, digits, and underscores) as a word. That sequence may also contain apostrophes ('
), but not more than one in a row. This means that aaa'bbb
is regarded as one word, but aaa''bbb
is regarded as two words. Apostrophes at the beginning or the end of a word are stripped by the FULLTEXT
parser; 'aaa'bbb'
would be parsed as aaa'bbb
.
The built-in FULLTEXT
parser determines where words start and end by looking for certain delimiter characters; for example, (space), ,
(comma), and .
(period). If words are not separated by delimiters (as in, for example, Chinese), the built-in FULLTEXT
parser cannot determine where a word begins or ends. To be able to add words or other indexed terms in such languages to a FULLTEXT
index that uses the built-in FULLTEXT
parser, you must preprocess them so that they are separated by some arbitrary delimiter such as "
. Alternatively, as of MySQL 5.7.6, you can create FULLTEXT
indexes using the ngram parser plugin (for Chinese, Japanese, or Korean) or the MeCab parser plugin (for Japanese).
It is possible to write a plugin that replaces the built-in full-text parser. For details, see [Section 26.2, “The MySQL Plugin API”]. For example parser plugin source code, see the plugin/fulltext
directory of a MySQL source distribution.
Some words are ignored in full-text searches:
-
Any word that is too short is ignored. The default minimum length of words that are found by full-text searches is three characters for InnoDB
search indexes, or four characters for MyISAM
. You can control the cutoff by setting a configuration option before creating the index: innodb_ft_min_token_size
configuration option for InnoDB
search indexes, or ft_min_word_len
for MyISAM
.
Note
This behavior does not apply to FULLTEXT
indexes that use the ngram parser. For the ngram parser, token length is defined by the ngram_token_size
option.
-
Words in the stopword list are ignored. A stopword is a word such as “the” or “some” that is so common that it is considered to have zero semantic value. There is a built-in stopword list, but it can be overridden by a user-defined list. The stopword lists and related configuration options are different for InnoDB
search indexes and MyISAM
ones. Stopword processing is controlled by the configuration options innodb_ft_enable_stopword
,innodb_ft_server_stopword_table
, and innodb_ft_user_stopword_table
for InnoDB
search indexes, andft_stopword_file
for MyISAM
ones.
See [Section 13.9.4, “Full-Text Stopwords”] to view default stopword lists and how to change them. The default minimum word length can be changed as described in [Section 13.9.6, “Fine-Tuning MySQL Full-Text Search”].
Every correct word in the collection and in the query is weighted according to its significance in the collection or query. Thus, a word that is present in many documents has a lower weight, because it has lower semantic value in this particular collection. Conversely, if the word is rare, it receives a higher weight. The weights of the words are combined to compute the relevance of the row. This technique works best with large collections.
MyISAM Limitation
For very small tables, word distribution does not adequately reflect their semantic value, and this model may sometimes produce bizarre results for search indexes on MyISAM
tables. For example, although the word “MySQL”is present in every row of the articles
table shown earlier, a search for the word in a MyISAM
search index produces no results:
1 | mysql> SELECT * FROM articles |
The search result is empty because the word “MySQL” is present in at least 50% of the rows, and so is effectively treated as a stopword. This filtering technique is more suitable for large data sets, where you might not want the result set to return every second row from a 1GB table, than for small data sets where it might cause poor results for popular terms.
The 50% threshold can surprise you when you first try full-text searching to see how it works, and makes InnoDB
tables more suited to experimentation with full-text searches. If you create a MyISAM
table and insert only one or two rows of text into it, every word in the text occurs in at least 50% of the rows. As a result, no search returns any results until the table contains more rows. Users who need to bypass the 50% limitation can build search indexes onInnoDB
tables, or use the boolean search mode explained in [Section 13.9.2, “Boolean Full-Text Searches”].
2. 布尔值全文搜索
MySQL can perform boolean full-text searches using the IN BOOLEAN MODE
modifier. With this modifier, certain characters have special meaning at the beginning or end of words in the search string. In the following query, the +
and -
operators indicate that a word must be present or absent, respectively, for a match to occur. Thus, the query retrieves all the rows that contain the word “MySQL” but that do not contain the word “YourSQL”:
1 | mysql> SELECT * FROM articles WHERE MATCH (title,body) |
Note
In implementing this feature, MySQL uses what is sometimes referred to as implied Boolean logic, in which
-+
stands for AND
--
stands for NOT
-
[no operator] implies OR
Boolean full-text searches have these characteristics:
-
They do not automatically sort rows in order of decreasing relevance.
-InnoDB
tables require a FULLTEXT
index on all columns of the MATCH()
expression to perform boolean queries. Boolean queries against a MyISAM
search index can work even without a FULLTEXT
index, although a search executed in this fashion would be quite slow.
-
The minimum and maximum word length full-text parameters apply to FULLTEXT
indexes created using the built-in FULLTEXT
parser and MeCab parser plugin. innodb_ft_min_token_size
and innodb_ft_max_token_size
are used for InnoDB
search indexes. ft_min_word_len
and ft_max_word_len
are used for MyISAM
search indexes.
Minimum and maximum word length full-text parameters do not apply to FULLTEXT
indexes created using the ngram parser. ngram token size is defined by the ngram_token_size
option.
-
The stopword list applies, controlled by innodb_ft_enable_stopword
, innodb_ft_server_stopword_table
, and innodb_ft_user_stopword_table
for InnoDB
search indexes, and ft_stopword_file
for MyISAM
ones.
-InnoDB
full-text search does not support the use of multiple operators on a single search word, as in this example: '++apple'
. Use of multiple operators on a single search word returns a syntax error to standard out. MyISAM full-text search will successfully process the same search ignoring all operators except for the operator immediately adjacent to the search word.
-InnoDB
full-text search only supports leading plus or minus signs. For example, InnoDB
supports '+apple'
but does not support 'apple+'
. Specifying a trailing plus or minus sign causes InnoDB
to report a syntax error.
-InnoDB
full-text search does not support the use of a leading plus sign with wildcard ('+*'
), a plus and minus sign combination ('+-'
), or leading a plus and minus sign combination ('+-apple'
). These invalid queries return a syntax error.
-InnoDB
full-text search does not support the use of the @
symbol in boolean full-text searches. The @
symbol is reserved for use by the @distance
proximity search operator.
-
They do not use the 50% threshold that applies to MyISAM
search indexes.
The boolean full-text search capability supports the following operators:
-+
A leading or trailing plus sign indicates that this word must be present in each row that is returned. InnoDB
only supports leading plus signs.
--
A leading or trailing minus sign indicates that this word must not be present in any of the rows that are returned. InnoDB
only supports leading minus signs.
Note: The -
operator acts only to exclude rows that are otherwise matched by other search terms. Thus, a boolean-mode search that contains only terms preceded by -
returns an empty result. It does not return “all rows except those containing any of the excluded terms.”
-
(no operator)
By default (when neither +
nor -
is specified), the word is optional, but the rows that contain it are rated higher. This mimics the behavior of MATCH() ... AGAINST()
without the IN BOOLEAN MODE
modifier.
-@*
distance*
This operator works on InnoDB
tables only. It tests whether two or more words all start within a specified distance from each other, measured in words. Specify the search words within a double-quoted string immediately before the@*
distance*
operator, for example, MATCH(col1) AGAINST('"word1 word2 word3" @8' IN BOOLEAN MODE)
-> <
These two operators are used to change a word’s contribution to the relevance value that is assigned to a row. The>
operator increases the contribution and the <
operator decreases it. See the example following this list.
-( )
Parentheses group words into subexpressions. Parenthesized groups can be nested.
-~
A leading tilde acts as a negation operator, causing the word’s contribution to the row’s relevance to be negative. This is useful for marking “noise” words. A row containing such a word is rated lower than others, but is not excluded altogether, as it would be with the -
operator.
-*
The asterisk serves as the truncation (or wildcard) operator. Unlike the other operators, it is appended to the word to be affected. Words match if they begin with the word preceding the *
operator.
If a word is specified with the truncation operator, it is not stripped from a boolean query, even if it is too short or a stopword. Whether a word is too short is determined from the innodb_ft_min_token_size
setting for InnoDB
tables, or ft_min_word_len
for MyISAM
tables. These options are not applicable to FULLTEXT
indexes that use the ngram parser.
The wildcarded word is considered as a prefix that must be present at the start of one or more words. If the minimum word length is 4, a search for '+*
word* +the*'
could return fewer rows than a search for '+*
word* +the'
, because the second query ignores the too-short search term the
.
-"
A phrase that is enclosed within double quote ("
) characters matches only rows that contain the phrase literally, as it was typed. The full-text engine splits the phrase into words and performs a search in the FULLTEXT
index for the words. Nonword characters need not be matched exactly: Phrase searching requires only that matches contain exactly the same words as the phrase and in the same order. For example, "test phrase"
matches "test, phrase"
.
If the phrase contains no words that are in the index, the result is empty. The words might not be in the index because of a combination of factors: if they do not exist in the text, are stopwords, or are shorter than the minimum length of indexed words.
The following examples demonstrate some search strings that use boolean full-text operators:
-'apple banana'
Find rows that contain at least one of the two words.
-'+apple +juice'
Find rows that contain both words.
-'+apple macintosh'
Find rows that contain the word “apple”, but rank rows higher if they also contain “macintosh”.
-'+apple -macintosh'
Find rows that contain the word “apple” but not “macintosh”.
-'+apple ~macintosh'
Find rows that contain the word “apple”, but if the row also contains the word “macintosh”, rate it lower than if row does not. This is “softer” than a search for '+apple -macintosh'
, for which the presence of “macintosh” causes the row not to be returned at all.
-'+apple +(>turnover <strudel)'
Find rows that contain the words “apple” and “turnover”, or “apple” and “strudel” (in any order), but rank “apple turnover” higher than “apple strudel”.
-'apple*'
Find rows that contain words such as “apple”, “apples”, “applesauce”, or “applet”.
-'"some words"'
Find rows that contain the exact phrase “some words” (for example, rows that contain “some words of wisdom” but not “some noise words”). Note that the "
characters that enclose the phrase are operator characters that delimit the phrase. They are not the quotation marks that enclose the search string itself.
Relevancy Rankings for InnoDB Boolean Mode Search
InnoDB
full-text search is modeled on the Sphinx full-text search engine, and the algorithms used are based onBM25 and TF-IDF ranking algorithms. For these reasons, relevancy rankings for InnoDB
boolean full-text search may differ from MyISAM
relevancy rankings.
InnoDB
uses a variation of the “term frequency-inverse document frequency” (TF-IDF
) weighting system to rank a document’s relevance for a given full-text search query. The TF-IDF
weighting is based on how frequently a word appears in a document, offset by how frequently the word appears in all documents in the collection. In other words, the more frequently a word appears in a document, and the less frequently the word appears in the document collection, the higher the document is ranked.
How Relevancy Ranking is Calculated
The term frequency (TF
) value is the number of times that a word appears in a document. The inverse document frequency (IDF
) value of a word is calculated using the following formula, where total_records
is the number of records in the collection, and matching_records
is the number of records that the search term appears in.
${IDF} = log10( ${total_records} / ${matching_records} )
When a document contains a word multiple times, the IDF value is multiplied by the TF value:
${TF} * ${IDF}
Using the TF
and IDF
values, the relevancy ranking for a document is calculated using this formula:
${rank} = ${TF} _ ${IDF} _ ${IDF}
The formula is demonstrated in the following examples.
Relevancy Ranking for a Single Word Search
This example demonstrates the relevancy ranking calculation for a single-word search.
1 | mysql> CREATE TABLE articles ( |
There are 8 records in total, with 3 that match the “database” search term. The first record (id 6
) contains the search term 6 times and has a relevancy ranking of 1.0886961221694946
. This ranking value is calculated using a TF
value of 6 (the “database” search term appears 6 times in record id 6
) and an IDF
value of 0.42596873216370745, which is calculated as follows (where 8 is the total number of records and 3 is the number of records that the search term appears in):
${IDF} = log10( 8 / 3 ) = 0.42596873216370745
The TF
and IDF
values are then entered into the ranking formula:
${rank} = ${TF} _ ${IDF} _ ${IDF}
Performing the calculation in the MySQL command-line client returns a ranking value of 1.088696164686938.
1 | mysql> SELECT 6*log10(8/3)*log10(8/3); |
Note
You may notice a slight difference in the ranking values returned by the SELECT ... MATCH ... AGAINST
statement and the MySQL command-line client (1.0886961221694946
versus 1.088696164686938
). The difference is due to how the casts between integers and floats/doubles are performed internally by InnoDB
(along with related precision and rounding decisions), and how they are performed elsewhere, such as in the MySQL command-line client or other types of calculators.
Relevancy Ranking for a Multiple Word Search
This example demonstrates the relevancy ranking calculation for a multiple-word full-text search based on thearticles
table and data used in the previous example.
If you search on more than one word, the relevancy ranking value is a sum of the relevancy ranking value for each word, as shown in this formula:
${rank} = ${TF} _ ${IDF} _ ${IDF} + ${TF} _ ${IDF} _ ${IDF}
Performing a search on two terms (‘mysql tutorial’) returns the following results:
1 | mysql> SELECT id, title, body, MATCH (title,body) AGAINST ('mysql tutorial' IN BOOLEAN MODE) |
In the first record (id 8
), ‘mysql’ appears once and ‘tutorial’ appears twice. There are six matching records for ‘mysql’ and two matching records for ‘tutorial’. The MySQL command-line client returns the expected ranking value when inserting these values into the ranking formula for a multiple word search:
1 | mysql> SELECT (1*log10(8/6)*log10(8/6)) + (2*log10(8/2)*log10(8/2)); |
Note
The slight difference in the ranking values returned by the SELECT ... MATCH ... AGAINST
statement and the MySQL command-line client is explained in the preceding example.
3. Full-Text Searches with Query Expansion
Full-text search supports query expansion (and in particular, its variant “blind query expansion”). This is generally useful when a search phrase is too short, which often means that the user is relying on implied knowledge that the full-text search engine lacks. For example, a user searching for “database” may really mean that “MySQL”, “Oracle”, “DB2”, and “RDBMS” all are phrases that should match “databases” and should be returned, too. This is implied knowledge.
Blind query expansion (also known as automatic relevance feedback) is enabled by adding WITH QUERY EXPANSION
or IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION
following the search phrase. It works by performing the search twice, where the search phrase for the second search is the original search phrase concatenated with the few most highly relevant documents from the first search. Thus, if one of these documents contains the word “databases” and the word “MySQL”, the second search finds the documents that contain the word“MySQL” even if they do not contain the word “database”. The following example shows this difference:
1 | mysql> SELECT * FROM articles |
Another example could be searching for books by Georges Simenon about Maigret, when a user is not sure how to spell “Maigret”. A search for “Megre and the reluctant witnesses” finds only “Maigret and the Reluctant Witnesses”without query expansion. A search with query expansion finds all books with the word “Maigret” on the second pass.
Note
Because blind query expansion tends to increase noise significantly by returning nonrelevant documents, use it only when a search phrase is short.
4. 全文禁止词
The stopword list is loaded and searched for full-text queries using the server character set and collation (the values of the character_set_server
and collation_server
system variables). False hits or misses might occur for stopword lookups if the stopword file or columns used for full-text indexing or searches have a character set or collation different from character_set_server
or collation_server
.
Case sensitivity of stopword lookups depends on the server collation. For example, lookups are case insensitive if the collation is latin1_swedish_ci
, whereas lookups are case sensitive if the collation is latin1_general_cs
orlatin1_bin
.
Stopwords for InnoDB Search Indexes
InnoDB
has a relatively short list of default stopwords, because documents from technical, literary, and other sources often use short words as keywords or in significant phrases. For example, you might search for “to be or not to be” and expect to get a sensible result, rather than having all those words ignored.
To see the default InnoDB
stopword list, query the INFORMATION_SCHEMA.INNODB_FT_DEFAULT_STOPWORD
table.
1 | mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_DEFAULT_STOPWORD; |
To define your own stopword list for all InnoDB
tables, define a table with the same structure as theINNODB_FT_DEFAULT_STOPWORD
table, populate it with stopwords, and set the value of theinnodb_ft_server_stopword_table
option to a value in the form *
db_name*/*
table_name*
before creating the full-text index. The stopword table must have a single VARCHAR
column named value
. The following example demonstrates creating and configuring a new global stopword table for InnoDB
.
– Create a new stopword table
1 | mysql> CREATE TABLE my_stopwords(value VARCHAR(30)) ENGINE = INNODB; |
– Insert stopwords (for simplicity, a single stopword is used in this example)
1 | mysql> INSERT INTO my_stopwords(value) VALUES ('Ishmael'); |
– Create the table
1 | mysql> CREATE TABLE opening_lines ( |
– Insert data into the table
1 | mysql> INSERT INTO opening_lines(opening_line,author,title) VALUES |
– Set the innodb_ft_server_stopword_table option to the new stopword table
1 | mysql> SET GLOBAL innodb_ft_server_stopword_table = 'test/my_stopwords'; |
– Create the full-text index (which rebuilds the table if no FTS_DOC_ID column is defined)
1 | mysql> CREATE FULLTEXT INDEX idx ON opening_lines(opening_line); |
Verify that the specified stopword (‘Ishmael’) does not appear by querying the words inINFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE
.
Note
By default, words less than 3 characters in length or greater than 84 characters in length do not appear in anInnoDB
full-text search index. Maximum and minimum word length values are configurable using theinnodb_ft_max_token_size
and innodb_ft_min_token_size
variables. This default behavior does not apply to the ngram parser plugin. ngram token size is defined by the ngram_token_size
option.
1 | mysql> SET GLOBAL innodb_ft_aux_table='test/opening_lines'; |
To create stopword lists on a table-by-table basis, create other stopword tables and use theinnodb_ft_user_stopword_table
option to specify the stopword table that you want to use before you create the full-text index.
Stopwords for MyISAM Search Indexes
The stopword file is loaded and searched using latin1
if character_set_server
is ucs2
, utf16
, utf16le
, or utf32
.
To override the default stopword list for MyISAM tables, set the ft_stopword_file
system variable. (See [Section 6.1.5, “Server System Variables”].) The variable value should be the path name of the file containing the stopword list, or the empty string to disable stopword filtering. The server looks for the file in the data directory unless an absolute path name is given to specify a different directory. After changing the value of this variable or the contents of the stopword file, restart the server and rebuild your FULLTEXT
indexes.
The stopword list is free-form, separating stopwords with any nonalphanumeric character such as newline, space, or comma. Exceptions are the underscore character (_
) and a single apostrophe ('
) which are treated as part of a word. The character set of the stopword list is the server’s default character set; see [Section 11.1.3.2, “Server Character Set and Collation”].
The following table shows the default list of stopwords for MyISAM
search indexes. In a MySQL source distribution, you can find this list in the storage/myisam/ft_static.c
file.
1 | | a's | able | about | above | according | |
5. 全文限制
-
Full-text searches are supported for InnoDB
and MyISAM
tables only.
-
Full-text searches are not supported for partitioned tables. See [Section 20.6, “Restrictions and Limitations on Partitioning”].
-
Full-text searches can be used with most multibyte character sets. The exception is that for Unicode, the utf8
character set can be used, but not the ucs2
character set. Although FULLTEXT
indexes on ucs2
columns cannot be used, you can perform IN BOOLEAN MODE
searches on a ucs2
column that has no such index.
The remarks for utf8
also apply to utf8mb4
, and the remarks for ucs2
also apply to utf16
, utf16le
, and utf32
.
-
Ideographic languages such as Chinese and Japanese do not have word delimiters. Therefore, the built-in full-text parser cannot determine where words begin and end in these and other such languages.
In MySQL 5.7.6, a character-based ngram full-text parser that supports Chinese, Japanese, and Korean (CJK), and a word-based MeCab parser plugin that supports Japanese are provided for use with InnoDB
and MySIAM
tables.
-
Although the use of multiple character sets within a single table is supported, all columns in a FULLTEXT
index must use the same character set and collation.
-
The MATCH()
column list must match exactly the column list in some FULLTEXT
index definition for the table, unless this MATCH()
is IN BOOLEAN MODE
on a MyISAM
table. For MyISAM
tables, boolean-mode searches can be done on nonindexed columns, although they are likely to be slow.
-
The argument to AGAINST()
must be a string value that is constant during query evaluation. This rules out, for example, a table column because that can differ for each row.
-
Index hints are more limited for FULLTEXT
searches than for non-FULLTEXT
searches. See [Section 9.9.4, “Index Hints”].
-
For InnoDB
, all DML operations (INSERT
, UPDATE
, DELETE
) involving columns with full-text indexes are processed at transaction commit time. For example, for an INSERT
operation, an inserted string is tokenized and decomposed into individual words. The individual words are then added to full-text index tables when the transaction is committed. As a result, full-text searches only return committed data.
-
The ‘%’ character is not a supported wildcard character for full-text searches.
6. Fine-Tuning MySQL Full-Text Search
MySQL’s full-text search capability has few user-tunable parameters. You can exert more control over full-text searching behavior if you have a MySQL source distribution because some changes require source code modifications. See [Section 2.9, “Installing MySQL from Source”].
Full-text search is carefully tuned for effectiveness. Modifying the default behavior in most cases can actually decrease effectiveness. Do not alter the MySQL sources unless you know what you are doing.
Most full-text variables described in this section must be set at server startup time. A server restart is required to change them; they cannot be modified while the server is running.
Some variable changes require that you rebuild the FULLTEXT
indexes in your tables. Instructions for doing so are given later in this section.
Configuring Minimum and Maximum Word Length
The minimum and maximum lengths of words to be indexed are defined by the innodb_ft_min_token_size
andinnodb_ft_max_token_size
for InnoDB
search indexes, and ft_min_word_len
and ft_max_word_len
forMyISAM
ones.
Note
Minimum and maximum word length full-text parameters do not apply to FULLTEXT
indexes created using the ngram parser. ngram token size is defined by the ngram_token_size
option.
After changing any of these options, rebuild your FULLTEXT
indexes for the change to take effect. For example, to make two-character words searchable, you could put the following lines in an option file:
1 | [mysqld] |
Then restart the server and rebuild your FULLTEXT
indexes. For MyISAM
tables, note the remarks regarding[myisamchk] in the instructions that follow for rebuilding MyISAM
full-text indexes.
Configuring the Natural Language Search Threshold
For MyISAM
search indexes, the 50% threshold for natural language searches is determined by the particular weighting scheme chosen. To disable it, look for the following line in storage/myisam/ftdefs.h
:
1 | #define GWS_IN_USE GWS_PROB |
Change that line to this:
1 | #define GWS_IN_USE GWS_FREQ |
Then recompile MySQL. There is no need to rebuild the indexes in this case.
Note
By making this change, you severely decrease MySQL’s ability to provide adequate relevance values for the MATCH()
function. If you really need to search for such common words, it would be better to search using IN BOOLEAN MODE
instead, which does not observe the 50% threshold.
Modifying Boolean Full-Text Search Operators
To change the operators used for boolean full-text searches on MyISAM
tables, set the ft_boolean_syntax
system variable. (InnoDB
does not have an equivalent setting.) This variable can be changed while the server is running, but you must have the SUPER
privilege to do so. No rebuilding of indexes is necessary in this case. See[Section 6.1.5, “Server System Variables”], which describes the rules governing how to set this variable.
Character Set Modifications
For the built-in full-text parser, you can change the set of characters that are considered word characters in several ways, as described in the following list. After making the modification, rebuild the indexes for each table that contains any FULLTEXT
indexes. Suppose that you want to treat the hyphen character (‘-‘) as a word character. Use one of these methods:
-
Modify the MySQL source: In storage/innobase/handler/ha_innodb.cc
(for InnoDB
), or instorage/myisam/ftdefs.h
(for MyISAM
), see the true_word_char()
and misc_word_char()
macros. Add '-'
to one of those macros and recompile MySQL.
-
Modify a character set file: This requires no recompilation. The true_word_char()
macro uses a “character type”table to distinguish letters and numbers from other characters. . You can edit the contents of the <ctype><map>
array in one of the character set XML files to specify that '-'
is a “letter.” Then use the given character set for yourFULLTEXT
indexes. For information about the <ctype><map>
array format, see [Section 11.3.1, “Character Definition Arrays”].
-
Add a new collation for the character set used by the indexed columns, and alter the columns to use that collation. For general information about adding collations, see [Section 11.4, “Adding a Collation to a Character Set”]. For an example specific to full-text indexing, see [Section 13.9.7, “Adding a Collation for Full-Text Indexing”].
Rebuilding InnoDB Full-Text Indexes
If you modify full-text variables that affect indexing (innodb_ft_min_token_size
, innodb_ft_max_token_size
,innodb_ft_server_stopword_table
, innodb_ft_user_stopword_table
, innodb_ft_enable_stopword
,ngram_token_size
you must rebuild your FULLTEXT
indexes after making the changes. Modifying theinnodb_ft_min_token_size
, innodb_ft_max_token_size
, or ngram_token_size
variables, which cannot be set dynamically, require restarting the server and rebuilding the indexes.
To rebuild the FULLTEXT
indexes for an InnoDB
table, use ALTER TABLE
with the DROP INDEX
and ADD INDEX
options to drop and re-create each index.
Optimizing InnoDB Full-Text Indexes
Running OPTIMIZE TABLE
on a table with a full-text index rebuilds the full-text index, removing deleted Document IDs and consolidating multiple entries for the same word, where possible.
To optimize a full-text index, enable innodb_optimize_fulltext_only
and run OPTIMIZE TABLE
.
1 | mysql> set GLOBAL innodb_optimize_fulltext_only=ON; |
To avoid lengthy rebuild times for full-text indexes on large tables, you can use theinnodb_ft_num_word_optimize
option to perform the optimization in stages. Theinnodb_ft_num_word_optimize
option defines the number of words that are optimized each time OPTIMIZE TABLE
is run. The default setting is 2000, which means that 2000 words are optimized each time OPTIMIZE TABLE
is run. Subsequent OPTIMIZE TABLE
operations continue from where the preceding OPTIMIZE TABLE
operation ended.
Rebuilding MyISAM Full-Text Indexes
If you modify full-text variables that affect indexing (ft_min_word_len
, ft_max_word_len
, or ft_stopword_file
), or if you change the stopword file itself, you must rebuild your FULLTEXT
indexes after making the changes and restarting the server.
To rebuild the FULLTEXT
indexes for a MyISAM
table, it is sufficient to do a QUICK
repair operation:
1 | mysql> REPAIR TABLE *`tbl_name`* QUICK; |
Alternatively, use ALTER TABLE
as just described. In some cases, this may be faster than a repair operation.
Each table that contains any FULLTEXT
index must be repaired as just shown. Otherwise, queries for the table may yield incorrect results, and modifications to the table will cause the server to see the table as corrupt and in need of repair.
If you use [myisamchk] to perform an operation that modifies MyISAM
table indexes (such as repair or analyze), theFULLTEXT
indexes are rebuilt using the default full-text parameter values for minimum word length, maximum word length, and stopword file unless you specify otherwise. This can result in queries failing.
The problem occurs because these parameters are known only by the server. They are not stored in MyISAM
index files. To avoid the problem if you have modified the minimum or maximum word length or stopword file values used by the server, specify the same ft_min_word_len
, ft_max_word_len
, and ft_stopword_file
values for[myisamchk] that you use for [mysqld]. For example, if you have set the minimum word length to 3, you can repair a table with [myisamchk] like this:
shell> myisamchk –recover –ft_min_word_len=3 tbl_name
.MYI
To ensure that [myisamchk] and the server use the same values for full-text parameters, place each one in both the [mysqld]
and [myisamchk]
sections of an option file:
1 | [mysqld] |
An alternative to using [myisamchk] for MyISAM
table index modification is to use the REPAIR TABLE
, ANALYZE TABLE
, OPTIMIZE TABLE
, or ALTER TABLE
statements. These statements are performed by the server, which knows the proper full-text parameter values to use.
7. Adding a Collation for Full-Text Indexing
This section describes how to add a new collation for full-text searches using the built-in full-text parser. The sample collation is like latin1_swedish_ci
but treats the '-'
character as a letter rather than as a punctuation character so that it can be indexed as a word character. General information about adding collations is given in [Section 11.4, “Adding a Collation to a Character Set”]; it is assumed that you have read it and are familiar with the files involved.
To add a collation for full-text indexing, use this procedure:
1.
Add a collation to the Index.xml
file. The collation ID must be unused, so choose a value different from 1000 if that ID is already taken on your system.
2.
Declare the sort order for the collation in the latin1.xml
file. In this case, the order can be copied fromlatin1_swedish_ci
:
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F
30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F
50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
60 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F
50 51 52 53 54 55 56 57 58 59 5A 7B 7C 7D 7E 7F
80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F
90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F
A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF
B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF
41 41 41 41 5C 5B 5C 43 45 45 45 45 49 49 49 49
44 4E 4F 4F 4F 4F 5D D7 D8 55 55 55 59 59 DE DF
41 41 41 41 5C 5B 5C 43 45 45 45 45 49 49 49 49
44 4E 4F 4F 4F 4F 5D F7 D8 55 55 55 59 59 DE FF
3.
Modify the ctype
array in latin1.xml
. Change the value corresponding to 0x2D (which is the code for the '-'
character) from 10 (punctuation) to 01 (small letter). In the following array, this is the element in the fourth row down, third value from the end.
00
20 20 20 20 20 20 20 20 20 28 28 28 28 28 20 20
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
48 10 10 10 10 10 10 10 10 10 10 10 10 01 10 10
84 84 84 84 84 84 84 84 84 84 10 10 10 10 10 10
10 81 81 81 81 81 81 01 01 01 01 01 01 01 01 01
01 01 01 01 01 01 01 01 01 01 01 10 10 10 10 10
10 82 82 82 82 82 82 02 02 02 02 02 02 02 02 02
02 02 02 02 02 02 02 02 02 02 02 10 10 10 10 20
10 00 10 02 10 10 10 10 10 10 01 10 01 00 01 00
00 10 10 10 10 10 10 10 10 10 02 10 02 00 02 01
48 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
01 01 01 01 01 01 01 10 01 01 01 01 01 01 01 02
02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02
02 02 02 02 02 02 02 10 02 02 02 02 02 02 02 02
4.
Restart the server.
5.
To employ the new collation, include it in the definition of columns that are to use it:
1 | mysql> DROP TABLE IF EXISTS t1; |
6.Test the collation to verify that hyphen is considered as a word character:
1 | mysql> INSERT INTO t1 VALUEs ('----'),('....'),('abcd'); |
8. ngram Full-Text Parser
The built-in MySQL full-text parser uses the white space between words as a delimiter to determine where words begin and end, which is a limitation when working with ideographic languages that do not use word delimiters. To address this limitation, MySQL provides an ngram full-text parser that supports Chinese, Japanese, and Korean (CJK). The ngram full-text parser is supported for use with InnoDB
and MyISAM
.
Note
MySQL also provides a MeCab full-text parser plugin for Japanese, which tokenizes documents into meaningful words. For more information, see [Section 13.9.9, “MeCab Full-Text Parser Plugin”].
An ngram is a contiguous sequence of n
characters from a given sequence of text. The ngram parser tokenizes a sequence of text into a contiguous sequence of n
characters. For example, you can tokenize “abcd” for different values of n
using the ngram full-text parser.
n=1: ‘a’, ‘b’, ‘c’, ‘d’
n=2: ‘ab’, ‘bc’, ‘cd’
n=3: ‘abc’, ‘bcd’
n=4: ‘abcd’
The ngram full-text parser, introduced in MySQL 5.7.6, is a built-in server plugin. As with other built-in server plugins, it is automatically loaded when the server is started.
The full-text search syntax described in [Section 13.9, “Full-Text Search Functions”] applies to the ngram parser plugin. Differences in parsing behavior are described in this section. Full-text-related configuration options, except for minimum and maximum word length options (innodb_ft_min_token_size
, innodb_ft_max_token_size
,ft_min_word_len
, ft_max_word_len
) are also applicable.
Configuring ngram Token Size
The ngram parser has a default ngram token size of 2 (bigram). For example, with a token size of 2, the ngram parser parses the string “abc def” into four tokens: “ab”, “bc”, “de” and “ef”.
ngram token size is configurable using the ngram_token_size
configuration option, which has a minimum value of 1 and maximum value of 10.
Typically, ngram_token_size
is set to the size of the largest token that you want to search for. If you only intend to search for single characters, set ngram_token_size
to 1. A smaller token size produces a smaller full-text search index, and faster searches. If you need to search for words comprised of more than one character, setngram_token_size
accordingly. For example, “Happy Birthday” is “生日快乐” in simplified Chinese, where “生日” is “birthday”, and “快乐” translates as “happy”. To search on two-character words such as these, setngram_token_size
to a value of 2 or higher.
As a read-only variable, ngram_token_size
may only be set as part of a startup string or in a configuration file:
- Startup string:
1 | mysqld --ngram_token_size=2 |
- Configuration file:
1 | [mysqld] |
Note
The following minimum and maximum word length configuration options are ignored for FULLTEXT
indexes that use the ngram parser: innodb_ft_min_token_size
, innodb_ft_max_token_size
, ft_min_word_len
, andft_max_word_len
.
Creating a FULLTEXT Index that Uses the ngram Parser
To create a FULLTEXT
index that uses the ngram parser, specify WITH PARSER ngram
with CREATE TABLE
, ALTER TABLE
, or CREATE INDEX
.
The following example demonstrates creating a table with an ngram
FULLTEXT
index, inserting sample data (Simplified Chinese text), and viewing tokenized data in the INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE
table.
1 | mysql> USE test; |
To add a FULLTEXT
index to an existing table, you can use ALTER TABLE
or CREATE INDEX
. For example:
1 | CREATE TABLE articles ( |
Or:
1 | CREATE FULLTEXT INDEX ft_index ON articles (title,body) WITH PARSER ngram; |
ngram Parser Space Handling
The ngram parser eliminates spaces when parsing. For example:
-
“ab cd” is parsed to “ab”, “cd”
-
“a bc” is parsed to “bc”
ngram Parser Stopword Handling
The built-in MySQL full-text parser compares words to entries in the stopword list. If a word is equal to an entry in the stopword list, the word is excluded from the index. For the ngram parser, stopword handling is performed differently. Instead of excluding tokens that are equal to entries in the stopword list, the ngram parser excludes tokens that contain stopwords. For example, assuming ngram_token_size=2
, a document that contains “a,b” is parsed to “a,” and “,b”. If a comma (“,”) is defined as a stopword, both “a,” and “,b” are excluded from the index because they contain a comma.
By default, the ngram parser uses the default stopword list, which contains a list of English stopwords. For a stopword list applicable to Chinese, Japanese, or Korean, you must create your own. For information about creating a stopword list, see [Section 13.9.4, “Full-Text Stopwords”].
Stopwords greater in length than ngram_token_size
are ignored.
ngram Parser Term Search
For natural language mode search, the search term is converted to a union of ngram terms. For example, the string “abc” (assuming ngram_token_size=2
) is converted to “ab bc”. Given two documents, one containing “ab” and the other containing “abc”, the search term “ab bc” matches both documents.
For boolean mode search, the search term is converted to an ngram phrase search. For example, the string ‘abc’ (assuming ngram_token_size=2
) is converted to ‘“ab bc”’. Given two documents, one containing ‘ab’ and the other containing ‘abc’, the search phrase ‘“ab bc”’ only matches the document containing ‘abc’.
ngram Parser Wildcard Search
Because an ngram FULLTEXT
index contains only ngrams, and does not contain information about the beginning of terms, wildcard searches may return unexpected results. The following behaviors apply to wildcard searches using ngram FULLTEXT
search indexes:
-
If the prefix term of a wildcard search is shorter than ngram token size, the query returns all indexed rows that contain ngram tokens starting with the prefix term. For example, assuming ngram_token_size=2
, a search on “a*”returns all rows starting with “a”.
-
If the prefix term of a wildcard search is longer than ngram token size, the prefix term is converted to an ngram phrase and the wildcard operator is ignored. For example, assuming ngram_token_size=2
, an “abc*” wildcard search is converted to “ab bc”.
ngram Parser Phrase Search
Phrase searches are converted to ngram phrase searches. For example, The search phrase “abc” is converted to“ab bc”, which returns documents containing “abc” and “ab bc”.
The search phrase “abc def” is converted to “ab bc de ef”, which returns documents containing “abc def” and “ab bc de ef”. A document that contains “abcdef” is not returned.
9. MeCab Full-Text Parser Plugin
The built-in MySQL full-text parser uses the white space between words as a delimiter to determine where words begin and end, which is a limitation when working with ideographic languages that do not use word delimiters. To address this limitation for Japanese, MySQL provides a MeCab full-text parser plugin. The MeCab full-text parser plugin is supported for use with InnoDB
and MyISAM
.
Note
MySQL also provides an ngram full-text parser plugin that supports Japanese. For more information, see[Section 13.9.8, “ngram Full-Text Parser”].
The MeCab full-text parser plugin, introduced in MySQL 5.7.6, is a full-text parser plugin for Japanese that tokenizes a sequence of text into meaningful words. For example, MeCab tokenizes “データベース管理” (“Database Management”) into “データベース” (“Database”) and “管理” (“Management”). By comparison, the [ngram] full-text parser tokenizes text into a contiguous sequence of n
characters, where n
represents a number between 1 and 10.
In addition to tokenizing text into meaningful words, MeCab indexes are typically smaller than ngram indexes, and MeCab full-text searches are generally faster. One drawback is that it may take longer for the MeCab full-text parser to tokenize documents, compared to the ngram full-text parser.
The full-text search syntax described in [Section 13.9, “Full-Text Search Functions”] applies to the MeCab parser plugin. Differences in parsing behavior are described in this section. Full-text related configuration options are also applicable.
For additional information about the MeCab parser, refer to the MeCab Documentation on the Google Developerssite.
Installing the MeCab Parser Plugin
The MeCab parser plugin requires mecab
and mecab-ipadic
.
On supported Fedora, Debian and Ubuntu platforms (except Ubuntu 12.04 where the system mecab
version is too old), MySQL dynamically links to the system mecab
installation if it is installed to the default location. On other supported Unix-like platforms, libmecab.so
is statically linked in libpluginmecab.so
, which is located in the MySQL plugin directory. mecab-ipadic
is included in MySQL binaries and is located in *
MYSQL_HOME*\lib\mecab
.
You can install mecab
and mecab-ipadic
using a native package management utility (on Fedora, Debian, and Ubuntu), or you can build mecab
and mecab-ipadic
from source. For information about installing mecab
andmecab-ipadic
using a native package management utility, see [Installing MeCab From a Binary Distribution (Optional)]”). If you want to build mecab
and mecab-ipadic
from source, see [Building MeCab From Source (Optional)]”).
On Windows, libmecab.dll
is found in the MySQL bin
directory. mecab-ipadic
is located in*
MYSQL_HOME*/lib/mecab
.
To install and configure the MeCab parser plugin, perform the following steps:
1.
In the MySQL configuration file, set the mecab_rc_file
configuration option to the location of the mecabrc
configuration file, which is the configuration file for MeCab. If you are using the MeCab package distributed with MySQL, the mecabrc
file is located in MYSQL_HOME/lib/mecab/etc/
.
1 | [mysqld] |
The loose
prefix is an [option modifier]. The mecab_rc_file
option is not recognized by MySQL until the MeCaB parser plugin is installed but it must be set before attempting to install the MeCaB parser plugin. The loose
prefix allows you restart MySQL without encountering an error due to an unrecognized variable.
If you use your own MeCab installation, or build MeCab from source, the location of the mecabrc
configuration file may differ.
For information about the MySQL configuration file and its location, see [Section 5.2.6, “Using Option Files”].
2.
Also in the MySQL configuration file, set the minimum token size to 1 or 2, which are the values recommended for use with the MeCab parser. For InnoDB
tables, minimum token size is defined by the innodb_ft_min_token_size
configuration option, which has a default value of 3. For MyISAM
tables, minimum token size is defined by ft_min_word_len
, which has a default value of 4.
[mysqld]
innodb_ft_min_token_size=1
3.
Modify the mecabrc
configuration file to specify the dictionary you want to use. The mecab-ipadic
package distributed with MySQL binaries includes three dictionaries (ipadic_euc-jp
, ipadic_sjis
, and ipadic_utf-8
). The mecabrc
configuration file packaged with MySQL contains and entry similar to the following:
dicdir = /path/to/mysql/lib/mecab/lib/mecab/dic/ipadic_euc-jp
To use the ipadic_utf-8
dictionary, for example, modify the entry as follows:
dicdir=MYSQL_HOME
/lib/mecab/dic/ipadic_utf-8
If you are using your own MeCab installation or have built MeCab from source, the default dicdir
entry in the mecabrc
file will differ, as will the dictionaries and their location.
Note
After the MeCab parser plugin is installed, you can use the mecab_charset
status variable to view the character set used with MeCab. The three MeCab dictionaries provided with the MySQL binary support the following character sets.
-
The ipadic_euc-jp
dictionary supports the ujis
and eucjpms
character sets.
-
The ipadic_sjis
dictionary supports the sjis
and cp932
character sets. cp932
support was added in MySQL 5.7.7.
-
The ipadic_utf-8
dictionary supports the utf8
and utf8mb4
character sets. utf8mb4
support was added in MySQL 5.7.7.
mecab_charset``ipadic_utf-8``utf8``utf8mb4``mecab_charset``utf8
4.
Restart MySQL.
5.
Install the MeCab parser plugin:
The MeCab parser plugin is installed using INSTALL PLUGIN
syntax. The plugin name is mecab
, and the shared library name is libpluginmecab.so
. For additional information about installing plugins, see [Section 6.5.2, “Installing and Uninstalling Plugins”].
INSTALL PLUGIN mecab SONAME ‘libpluginmecab.so’;
Once installed, the MeCab parser plugin loads at every normal MySQL restart.
6.
Verify that the MeCab parser plugin is loaded using the SHOW PLUGINS
statement.
1 | mysql> SHOW PLUGINS; |
A mecab
plugin should appear in the list of plugins.
Creating a FULLTEXT Index that uses the MeCab Parser
To create a FULLTEXT
index that uses the mecab parser, specify WITH PARSER ngram
with CREATE TABLE
, ALTER TABLE
, or CREATE INDEX
.
This example demonstrates creating a table with a mecab
FULLTEXT
index, inserting sample data, and viewing tokenized data in the INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE
table:
1 | mysql> USE test; |
To add a FULLTEXT
index to an existing table, you can use ALTER TABLE
or CREATE INDEX
. For example:
1 | CREATE TABLE articles ( |
Or:
1 | CREATE FULLTEXT INDEX ft_index ON articles (title,body) WITH PARSER mecab; |
MeCab Parser Space Handling
The MeCab parser uses spaces as separators in query strings. For example, the MeCab parser tokenizes ‘データベース管理’ as ‘データベース’ and ‘管理’.
MeCab Parser Stopword Handling
By default, the MeCab parser uses the default stopword list, which contains a short list of English stopwords. For a stopword list applicable to Japanese, you must create your own. For information about creating stopword lists, see[Section 13.9.4, “Full-Text Stopwords”].
MeCab Parser Term Search
For natural language mode search, the search term is converted to a union of tokens. For example, ‘データベース管理’ is converted to ‘データベース 管理’ .
1 | SELECT COUNT(*) FROM articles WHERE MATCH(title,body) AGAINST('データベース管理' IN NATURAL LANGUAGE MODE); |
For boolean mode search, the search term is converted to a search phrase. For example, ‘データベース管理’ is converted to ‘“データベース 管理”‘.
1 | SELECT COUNT(*) FROM articles WHERE MATCH(title,body) AGAINST('データベース管理' IN BOOLEAN MODE); |
MeCab Parser Wildcard Search
Wildcard search terms are not tokenized. A search on ‘データベース管理*’ is performed on the prefix, ‘データベース管理’.
1 | SELECT COUNT(*) FROM articles WHERE MATCH(title,body) AGAINST('データベース*' IN BOOLEAN MODE); |
MeCab Parser Phrase Search
Phrases are tokenized. For example, “データベース管理” is tokenized as “データベース 管理”.
SELECT COUNT(*) FROM articles WHERE MATCH(title,body) AGAINST(‘“データベース管理”‘ IN BOOLEAN MODE);
Installing MeCab From a Binary Distribution (Optional)
This section describes how to install mecab
and mecab-ipadic
from a binary distribution using a native package management utility. For example, on Fedora, you can use Yum to perform the installation:
1 | yum mecab-devel |
On Debian or Ubuntu, you can perform an APT installation:
1 | apt-get install mecab |
Installing MeCab From Source (Optional)
If you want to build mecab
and mecab-ipadic
from source, basic installation steps are provided below. For additional information, refer to the MeCab documentation.
1.
Download the tar.gz packages for mecab
and mecab-ipadic
from http://taku910.github.io/mecab/#download. As of February, 2016, the latest available packages are mecab-0.996.tar.gz
and mecab-ipadic-2.7.0-20070801.tar.gz
.
2.
Install mecab
:
1 | tar zxfv mecab-0.996.tar |
3.
Install mecab-ipadic
:
1 | tar zxfv mecab-ipadic-2.7.0-20070801.tar |
4.
Compile MySQL using the WITH_MECAB
CMake option. Set the WITH_MECAB
option to system
if you have installedmecab
and mecab-ipadic
to the default location.
-DWITH_MECAB=system
If you defined a custom installation directory, set WITH_MECAB
to the custom directory. For example:
-DWITH_MECAB=/path/to/mecab
语雀镜像 : [mysql] 13.9 Full-Text 搜索函数 ,点此 提问
[mysql] 13.9 Full-Text 搜索函数
https://wulicode.com/mysql/mysql-139-fulltext-sou-suo-han-shu.html