Spec-Zone .ru
спецификации, руководства, описания, API

12.9.1. Естественный язык Полнотекстовые Поискы

По умолчанию или с IN NATURAL LANGUAGE MODE модификатор, MATCH() функция выполняет поиск естественного языка строки против текстового набора. Набор является рядом того или большего количества столбцов, включенных в a FULLTEXT индексировать. Строка поиска дается как параметр AGAINST(). Для каждой строки в таблице, MATCH() возвращает значение уместности; то есть, мера по подобию между строкой поиска и текстом в той строке в столбцах, названных в MATCH() список.

mysql> CREATE TABLE articles
        (     id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY
        KEY,     title VARCHAR(200),     body TEXT,     FULLTEXT
        (title,body)    ) ENGINE=InnoDB;Query OK, 0 rows affected (0.00 sec)mysql> INSERT INTO articles (title,body) VALUES    ('MySQL Tutorial','DBMS stands for DataBase ...'),    ('How To Use MySQL Well','After you went through a ...'),    ('Optimizing MySQL','In this tutorial we will show ...'),    ('1001 MySQL Tricks','1. Never run mysqld as root. 2.
        ...'),    ('MySQL vs. YourSQL','In the following database
        comparison ...'),    ('MySQL Security','When configured
        properly, MySQL ...');Query OK, 6 rows affected (0.00 sec)Records: 6  Duplicates: 0  Warnings: 0mysql> SELECT * FROM articles    WHERE
        MATCH (title,body)    AGAINST ('database' IN NATURAL LANGUAGE
        MODE);+----+-------------------+------------------------------------------+| id | title             | body                                     |+----+-------------------+------------------------------------------+|  1 | MySQL Tutorial    | DBMS stands for DataBase ...             ||  5 | MySQL vs. YourSQL | In the following database comparison ... |+----+-------------------+------------------------------------------+2 rows in set (0.00 sec)

По умолчанию поиск выполняется нечувствительным к регистру способом. Чтобы выполнить чувствительный к регистру полнотекстовый поиск, используйте двоичное сопоставление для индексированных столбцов. Например, столбец, который использует latin1 набор символов может быть присвоен сопоставление latin1_bin сделать это чувствительным к регистру для полнотекстовых поисков.

Когда MATCH() используется в a WHERE пункт, как в примере, показанном ранее, возвращенные строки, автоматически сортируется с самой высокой уместностью сначала. Значения уместности являются неотрицательными числами с плавающей точкой. Нулевая уместность не означает подобия. Уместность вычисляется основанная на числе слов в строке, числе уникальных слов в той строке, общем количестве слов в наборе, и числе документов (строки), которые содержат определенное слово.

Чтобы просто считать соответствия, Вы могли использовать запрос как это:

mysql> SELECT COUNT(*) FROM articles    WHERE MATCH (title,body)    AGAINST
        ('database' IN NATURAL LANGUAGE MODE);+----------+| COUNT(*) |+----------+|        2 |+----------+1 row in set (0.00 sec)

Вы могли бы счесть более быстрым, чтобы переписать запрос следующим образом:

mysql> SELECT    COUNT(IF(MATCH (title,body) AGAINST ('database' IN NATURAL LANGUAGE MODE), 1,
        NULL))    AS count    FROM
        articles;+-------+| count |+-------+|     2 |+-------+1 row in set (0.03 sec)

Первый запрос делает некоторую дополнительную работу (сортирующий результаты уместностью), но также и может использовать индексировать поиск, основанный на WHERE пункт. Индексировать поиск мог бы сделать первый запрос быстрее, если поиск соответствует немного строк. Второй запрос выполняет полное сканирование таблицы, которое могло бы быть быстрее чем индексировать поиск, если бы критерий поиска присутствовал в большинстве строк.

Для естественного языка полнотекстовые поискы, столбцы, названные в MATCH() функция должна быть теми же самыми столбцами, включенными в некоторых FULLTEXT индексируйте в своей таблице. Для предыдущего запроса отметьте что столбцы, названные в MATCH() функция (title и body) то же самое как названные в определении article таблица FULLTEXT индексировать. Искать title или body отдельно, Вы создали бы отдельный FULLTEXT индексирует для каждого столбца.

Можно также выполнить булев поиск или поиск с расширением запроса. Эти типы поиска описываются в Разделе 12.9.2, "Булевы Полнотекстовые Поискы", и Раздел 12.9.3, "Полнотекстовые Поискы с Расширением Запроса".

Полнотекстовый поиск, который использует индексирование, может назвать столбцы только от единственной таблицы в MATCH() пункт, потому что индексирование не может охватить многократные таблицы. Для MyISAM таблицы, булев поиск может быть сделан в отсутствие индексирования (хотя более медленно), когда возможно назвать столбцы от многократных таблиц.

Предыдущим примером является основная иллюстрация, которая показывает, как использовать MATCH() функционируйте, куда строки возвращаются в порядке уменьшающейся уместности. Следующий пример показывает, как получить значения уместности явно. Возвращенные строки не упорядочиваются потому что SELECT оператор не включает ни одного WHERE ни ORDER BY пункты:

mysql> SELECT id, MATCH (title,body)    AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE) AS score    FROM articles;+----+---------------------+| id | score               |+----+---------------------+|  1 | 0.22764469683170319 ||  2 |                   0 ||  3 | 0.22764469683170319 ||  4 |                   0 ||  5 |                   0 ||  6 |                   0 |+----+---------------------+6 rows in set (0.00 sec)

Следующий пример более сложен. Запрос возвращает значения уместности, и он также сортирует строки в порядке уменьшающейся уместности. Чтобы достигнуть этого результата, определить MATCH() дважды: однажды в SELECT список и однажды в WHERE пункт. Это не вызывает дополнительных издержек, потому что оптимизатор MySQL замечает что два MATCH() вызовы идентичны, и вызывает полнотекстовый код поиска только однажды.

mysql> SELECT id, body, MATCH (title,body)
        AGAINST    ('Security implications of running MySQL as
        root'    IN NATURAL LANGUAGE MODE) AS
        score    FROM articles WHERE MATCH (title,body)
        AGAINST    ('Security implications of running MySQL as
        root'    IN NATURAL LANGUAGE MODE);+----+-----------------------+------------------------------------------+| id | title                 | body                                     |+----+-----------------------+------------------------------------------+|  5 | MySQL vs. YourSQL     | In the following database comparison ... ||  1 | MySQL Tutorial        | DBMS stands for DataBase ...             ||  3 | Optimizing MySQL      | In this tutorial we will show ...        ||  6 | MySQL Security        | When configured properly, MySQL ...      ||  2 | How To Use MySQL Well | After you went through a ...             ||  4 | 1001 MySQL Tricks     | 1. Never run mysqld as root. 2. ...      |+----+-----------------------+------------------------------------------+6 rows in set (0.00 sec)

MySQL FULLTEXT реализация расценивает любую последовательность истинных символов слова (буквы, цифры, и подчеркивания) как слово. Та последовательность может также содержать апострофы ("'"), но не больше чем один подряд. Это означает это aaa'bbb расценивается как одно слово, но aaa''bbb расценивается как два слова. Апострофы вначале или конец слова разделяются FULLTEXT синтаксический анализатор; 'aaa'bbb' был бы проанализирован как aaa'bbb.

FULLTEXT синтаксический анализатор определяет, где слова запускаются и заканчиваются, ища определенные символы-разделители; например," "(пространство),","(запятая), и"."(период). Если слова не разделяются разделителями (как в, например, китайский язык), FULLTEXT синтаксический анализатор не может определить, где слово начинается или заканчивается. Быть в состоянии добавить слова или другие индексированные сроки на таких языках к a FULLTEXT индексируйте, следует предварительно обработать их так, чтобы они были разделены некоторым произвольным разделителем такой как""".

В MySQL 5.7 возможно записать плагин, который заменяет встроенный полнотекстовый синтаксический анализатор. Для получения дополнительной информации см. Раздел 22.2, "API MySQL Plugin". Например исходный код плагина синтаксического анализатора, см. plugin/fulltext каталог исходного распределения MySQL.

Некоторые слова игнорируются в полнотекстовых поисках:

Значение по умолчанию stopword списки показывают в Разделе 12.9.4, "Полнотекстовый Stopwords". Длина слова минимума значения по умолчанию и список stopword могут быть изменены как описано в Разделе 12.9.6, "MySQL Fine-Tuning Полнотекстовый Поиск".

Каждое корректное слово в наборе и в запросе взвешивается согласно его значению в наборе или запросе. Таким образом у слова, которое присутствует во многих документах, есть более низкий вес, потому что у него есть более низкое семантическое значение в этом определенном наборе. Наоборот, если слово редко, оно получает более высокий вес. Веса слов объединяются, чтобы вычислить уместность строки. Этот метод работает лучше всего с большим количеством.

Ограничение MyISAM

Для очень маленьких таблиц распределение слова не соответственно отражает их семантическое значение, и эта модель может иногда приводить к причудливым результатам для поиска, индексирует на MyISAM таблицы. Например, хотя слово "MySQL" присутствует в каждой строке articles таблица, показанная ранее, поиск слова в a MyISAM поиск индексирует, не приводит ни к каким результатам:

mysql> SELECT * FROM articles    WHERE MATCH (title,body)    AGAINST
            ('MySQL' IN NATURAL LANGUAGE MODE);Empty set (0.00 sec)

Результат поиска пуст, потому что слово "MySQL" присутствует по крайней мере в 50 % строк, и так эффективно обрабатывается как stopword. Этот метод фильтрации является более подходящим для больших наборов данных, где Вы не могли бы хотеть, чтобы набор результатов возвратил каждую вторую строку из таблицы на 1 Гбайт, чем для небольших наборов данных, где это могло бы вызвать плохие результаты для популярных сроков.

50%-ый порог может удивить Вас, когда Вы сначала пробуете полнотекстовый поиск, чтобы видеть, как это работает, и делает InnoDB таблицы больше подходящее для экспериментирования с полнотекстовыми поисками. Если Вы создаете a MyISAM таблица и вставляет только одну или две строки текста в это, каждое слово в тексте происходит по крайней мере в 50 % строк. В результате никакой поиск не возвращает результатов, пока таблица не содержит больше строк. Пользователи, которые должны обойти 50%-ое ограничение, могут создать поиск, индексирует на InnoDB таблицы, или булев режим поиска, объясненный в Разделе 12.9.2, "Булевы Полнотекстовые Поискы".