sql >> データベース >  >> RDS >> Mysql

MySQLでのMATCH()関数のしくみ

    MySQLでは、 MATCH() 関数は全文検索を実行します。検索するテーブル列のコンマ区切りリストを受け入れます。

    テーブルにはFULLTEXTが必要です それらに対して全文検索を実行する前にインデックスを作成します(ただし、 MyISAMに対するブールクエリ FULLTEXT がなくても、検索インデックスは(ゆっくりではありますが)機能します。 索引)。

    FULLTEXTを作成できます テーブルを作成するときのインデックス( CREATE TABLE を使用) ステートメント)、または ALTER TABLEを使用できます ステートメントまたはCREATEINDEX テーブルがすでに存在する場合はステートメント。

    デフォルトでは、検索では大文字と小文字が区別されません。大文字と小文字を区別する検索を実行するには、インデックス付きの列に大文字と小文字を区別する照合またはバイナリ照合を使用します。

    構文

    MATCH()の構文 関数は次のようになります:

    MATCH (col1,col2,...) AGAINST (expr [search_modifier])

    ここで、 col1、col2、... 検索する列のコンマ区切りリストであり、 expr 入力文字列/式です。

    オプションのsearch_modifier 引数を使用すると、検索タイプを指定できます。次のいずれかの値になります。

    • 自然言語モード
    • クエリ拡張機能を備えた自然言語モード
    • ブールモード
    • クエリ拡張あり

    デフォルトのモードはINNATURAL LANGUAGE MODEです。 。

    例1-基本的な使用法

    この関数の使用例は次のとおりです。

    SELECT AlbumId, AlbumName
    FROM Albums
    WHERE MATCH(AlbumName) AGAINST('cool');
    

    結果:

    +---------+--------------------+
    | AlbumId | AlbumName          |
    +---------+--------------------+
    |       5 | Casualties of Cool |
    +---------+--------------------+
    

    上記のクエリが実行された完全なテーブルは次のとおりです。

    SELECT AlbumId, AlbumName
    FROM Albums;
    

    結果:

    +---------+--------------------------+
    | AlbumId | AlbumName                |
    +---------+--------------------------+
    |       1 | Powerslave               |
    |       2 | Powerage                 |
    |       3 | Singing Down the Lane    |
    |       4 | Ziltoid the Omniscient   |
    |       5 | Casualties of Cool       |
    |       6 | Epicloud                 |
    |       7 | Somewhere in Time        |
    |       8 | Piece of Mind            |
    |       9 | Killers                  |
    |      10 | No Prayer for the Dying  |
    |      11 | No Sound Without Silence |
    |      12 | Big Swing Face           |
    |      13 | Blue Night               |
    |      14 | Eternity                 |
    |      15 | Scandinavia              |
    |      16 | Long Lost Suitcase       |
    |      17 | Praise and Blame         |
    |      18 | Along Came Jones         |
    |      19 | All Night Wrong          |
    |      20 | The Sixteen Men of Tain  |
    +---------+--------------------------+
    

    例2–エラー:「フルテキストインデックスが見つかりません」

    InnoDB テーブルにはFULLTEXTが必要です 全文検索の結果を返す前にインデックスを作成します。 FULLTEXTがない場合 インデックスを作成すると、次のエラーが発生する可能性があります。

    ERROR 1191 (HY000): Can't find FULLTEXT index matching the column list
    

    そのエラーが発生した場合は、 FULLTEXTを追加する必要があります 検索しようとしているすべての列のインデックス(次の例を参照)。

    これの例外は、 MyISAMに対してブールクエリを実行している場合です。 検索インデックス。

    具体的には、ブール全文検索に関するMySQLのドキュメントには次のように記載されています。

    InnoDB テーブルにはFULLTEXTが必要です MATCH()のすべての列のインデックス ブールクエリを実行する式。 MyISAMに対するブールクエリ 検索インデックスは、 FULLTEXTがなくても機能します インデックス。ただし、この方法で実行される検索は非常に遅くなります。

    例3–既存のテーブルへのフルテキストインデックスの追加

    FULLTEXTを追加する例を次に示します。 既存のテーブルへのインデックス:

    ALTER TABLE Albums  
    ADD FULLTEXT(AlbumName);
    

    この場合、 AlbumNameのコンテンツにインデックスを付けました 桁。

    複数の列にインデックスを付けるには、それらをコンマで区切ります(次の例を参照)。

    例4–複数の列の検索

    複数の列を検索する必要があると思われる場合は、検索するすべての列を含むインデックスを作成する必要があります。これを行うには、各列をコンマ区切りのリストとして含めるだけです。

    FULLTEXTを追加する例を次に示します。 filmのインデックス テーブル(Sakilaサンプルデータベースの一部です)。

    ALTER TABLE film 
    ADD FULLTEXT(title, description);
    

    この場合、 titleの内容にインデックスを付けます およびdescription 列。

    これで、 FULLTEXTが作成されました。 両方の列のインデックスを作成すると、それらに対して全文検索を実行できます:

    SELECT title, description
    FROM film
    WHERE MATCH(title, description) AGAINST('vertigo');
    

    結果:

    +-------------------+-----------------------------------------------------------------------------------------------------------+
    | title             | description                                                                                               |
    +-------------------+-----------------------------------------------------------------------------------------------------------+
    | VERTIGO NORTHWEST | A Unbelieveable Display of a Mad Scientist And a Mad Scientist who must Outgun a Mad Cow in Ancient Japan |
    +-------------------+-----------------------------------------------------------------------------------------------------------+
    

    別の検索では、正確なキーフレーズは一致しませんが、そのフレーズ内の各キーワードは一致します。

    SELECT title, description
    FROM film
    WHERE MATCH(title, description) AGAINST('Iron Maiden');
    

    結果:

    +-------------+---------------------------------------------------------------------------------------------------------+
    | title       | description                                                                                             |
    +-------------+---------------------------------------------------------------------------------------------------------+
    | IRON MOON   | A Fast-Paced Documentary of a Mad Cow And a Boy who must Pursue a Dentist in A Baloon                   |
    | MAIDEN HOME | A Lacklusture Saga of a Moose And a Teacher who must Kill a Forensic Psychologist in A MySQL Convention |
    +-------------+---------------------------------------------------------------------------------------------------------+
    

    完全に一致するフレーズのみが必要な場合は、その前後に二重引用符を付けます。

    SELECT title, description
    FROM film
    WHERE MATCH(title, description) AGAINST('"Iron Maiden"');
    

    結果:

    Empty set (0.00 sec)
    

    この場合、どの列にもその正確なフレーズは含まれていません。

    例5–関連性スコアを返す

    MATCH()を使用するときはいつでも 関数では、テーブルの各行に関連性の値が割り当てられます。つまり、各行は、検索語との関連性を決定するスコアを取得します。次に、結果は関連性の順に並べられます(関連性が最も高いものが最初になります)。

    関連性の値は、非負の浮動小数点数です。関連性がゼロの場合、類似性がないことを意味します。関連性は、行(ドキュメント)内の単語数、行内の一意の単語数、コレクション内の単語の総数、および特定の単語を含む行数に基​​づいて計算されます。

    各結果の関連性を返すには、 MATCH()を含めるだけです。 選択する列のリストで機能します。

    例:

    SELECT 
      MATCH(title, description) AGAINST('Iron Maiden') AS Relevance,
      title, 
      description
    FROM film
    WHERE MATCH(title, description) AGAINST('Iron Maiden');
    

    結果:

    +-----------+-------------+---------------------------------------------------------------------------------------------------------+
    | Relevance | title       | description                                                                                             |
    +-----------+-------------+---------------------------------------------------------------------------------------------------------+
    |         9 | IRON MOON   | A Fast-Paced Documentary of a Mad Cow And a Boy who must Pursue a Dentist in A Baloon                   |
    |         9 | MAIDEN HOME | A Lacklusture Saga of a Moose And a Teacher who must Kill a Forensic Psychologist in A MySQL Convention |
    +-----------+-------------+---------------------------------------------------------------------------------------------------------+
    

    この場合、関連性スコアは両方の行で非常に高くなっています。

    関連性が低いもう1つの例は次のとおりです。

    SELECT 
      MATCH(title, description) AGAINST('Saga of a Moose') AS Relevance,
      title, 
      description
    FROM film
    WHERE MATCH(title, description) AGAINST('Saga of a Moose')
    LIMIT 15;
    

    結果:

    +--------------------+------------------------+---------------------------------------------------------------------------------------------------------+
    | Relevance          | title                  | description                                                                                             |
    +--------------------+------------------------+---------------------------------------------------------------------------------------------------------+
    | 2.4431142807006836 | CAPER MOTIONS          | A Fateful Saga of a Moose And a Car who must Pursue a Woman in A MySQL Convention                       |
    | 2.4431142807006836 | DATE SPEED             | A Touching Saga of a Composer And a Moose who must Discover a Dentist in A MySQL Convention             |
    | 2.4431142807006836 | DELIVERANCE MULHOLLAND | A Astounding Saga of a Monkey And a Moose who must Conquer a Butler in A Shark Tank                     |
    | 2.4431142807006836 | FLASH WARS             | A Astounding Saga of a Moose And a Pastry Chef who must Chase a Student in The Gulf of Mexico           |
    | 2.4431142807006836 | HAROLD FRENCH          | A Stunning Saga of a Sumo Wrestler And a Student who must Outrace a Moose in The Sahara Desert          |
    | 2.4431142807006836 | MAIDEN HOME            | A Lacklusture Saga of a Moose And a Teacher who must Kill a Forensic Psychologist in A MySQL Convention |
    | 2.4431142807006836 | SHANE DARKNESS         | A Action-Packed Saga of a Moose And a Lumberjack who must Find a Woman in Berlin                        |
    | 2.4431142807006836 | SLEEPLESS MONSOON      | A Amazing Saga of a Moose And a Pastry Chef who must Escape a Butler in Australia                       |
    | 2.4431142807006836 | WAKE JAWS              | A Beautiful Saga of a Feminist And a Composer who must Challenge a Moose in Berlin                      |
    | 2.4431142807006836 | WONKA SEA              | A Brilliant Saga of a Boat And a Mad Scientist who must Meet a Moose in Ancient India                   |
    | 1.2399028539657593 | AIRPLANE SIERRA        | A Touching Saga of a Hunter And a Butler who must Discover a Butler in A Jet Boat                       |
    | 1.2399028539657593 | ALASKA PHANTOM         | A Fanciful Saga of a Hunter And a Pastry Chef who must Vanquish a Boy in Australia                      |
    | 1.2399028539657593 | ARMY FLINTSTONES       | A Boring Saga of a Database Administrator And a Womanizer who must Battle a Waitress in Nigeria         |
    | 1.2399028539657593 | BEAR GRACELAND         | A Astounding Saga of a Dog And a Boy who must Kill a Teacher in The First Manned Space Station          |
    | 1.2399028539657593 | BERETS AGENT           | A Taut Saga of a Crocodile And a Boy who must Overcome a Technical Writer in Ancient China              |
    +--------------------+------------------------+---------------------------------------------------------------------------------------------------------+
    

    LIMIT 15 を使用していなかった場合、結果セットははるかに大きくなることに注意してください。 結果の数を15に制限します。

    例6–特定の関連性スコアを超える結果のみを返す

    前の例をさらに一歩進めて、特定の関連性スコアを持つ結果のみを除外することができます。この場合、関連性スコアは2より高くなければならないことを指定します。

    ただし、これを行うときは注意してください。上記のように、関連性の値は、列に含まれるテキストの量、検索語に一致する他の行の数などの要因に応じて、非常に高くなることも低くなることもあります。

    SELECT 
      MATCH(title, description) AGAINST('Saga of a Moose') AS Relevance,
      title, 
      description
    FROM film
    WHERE MATCH(title, description) AGAINST('Saga of a Moose') > 2;
    

    結果:

    +--------------------+------------------------+---------------------------------------------------------------------------------------------------------+
    | Relevance          | title                  | description                                                                                             |
    +--------------------+------------------------+---------------------------------------------------------------------------------------------------------+
    | 2.4431142807006836 | CAPER MOTIONS          | A Fateful Saga of a Moose And a Car who must Pursue a Woman in A MySQL Convention                       |
    | 2.4431142807006836 | DATE SPEED             | A Touching Saga of a Composer And a Moose who must Discover a Dentist in A MySQL Convention             |
    | 2.4431142807006836 | DELIVERANCE MULHOLLAND | A Astounding Saga of a Monkey And a Moose who must Conquer a Butler in A Shark Tank                     |
    | 2.4431142807006836 | FLASH WARS             | A Astounding Saga of a Moose And a Pastry Chef who must Chase a Student in The Gulf of Mexico           |
    | 2.4431142807006836 | HAROLD FRENCH          | A Stunning Saga of a Sumo Wrestler And a Student who must Outrace a Moose in The Sahara Desert          |
    | 2.4431142807006836 | MAIDEN HOME            | A Lacklusture Saga of a Moose And a Teacher who must Kill a Forensic Psychologist in A MySQL Convention |
    | 2.4431142807006836 | SHANE DARKNESS         | A Action-Packed Saga of a Moose And a Lumberjack who must Find a Woman in Berlin                        |
    | 2.4431142807006836 | SLEEPLESS MONSOON      | A Amazing Saga of a Moose And a Pastry Chef who must Escape a Butler in Australia                       |
    | 2.4431142807006836 | WAKE JAWS              | A Beautiful Saga of a Feminist And a Composer who must Challenge a Moose in Berlin                      |
    | 2.4431142807006836 | WONKA SEA              | A Brilliant Saga of a Boat And a Mad Scientist who must Meet a Moose in Ancient India                   |
    +--------------------+------------------------+---------------------------------------------------------------------------------------------------------+
    

    例7–関連性ゼロの結果を含める

    関連性の値がゼロの場合でも、各行の関連性の値を一覧表示する例を次に示します。 MATCH()を使用しないことでこれを行うことができます WHEREで機能する 句。

    この例では、実際には WHEREを使用していません 句。 LIMITのみを使用します 結果の数を制限する句。

    SELECT 
      MATCH(title, description) AGAINST('Scientist') AS Relevance,
      title, 
      description
    FROM film
    LIMIT 15;
    

    結果:

    +-------------------+------------------+-----------------------------------------------------------------------------------------------------------------------+
    | Relevance         | title            | description                                                                                                           |
    +-------------------+------------------+-----------------------------------------------------------------------------------------------------------------------+
    | 1.026631474494934 | ACADEMY DINOSAUR | A Epic Drama of a Feminist And a Mad Scientist who must Battle a Teacher in The Canadian Rockies                      |
    |                 0 | ACE GOLDFINGER   | A Astounding Epistle of a Database Administrator And a Explorer who must Find a Car in Ancient China                  |
    |                 0 | ADAPTATION HOLES | A Astounding Reflection of a Lumberjack And a Car who must Sink a Lumberjack in A Baloon Factory                      |
    |                 0 | AFFAIR PREJUDICE | A Fanciful Documentary of a Frisbee And a Lumberjack who must Chase a Monkey in A Shark Tank                          |
    |                 0 | AFRICAN EGG      | A Fast-Paced Documentary of a Pastry Chef And a Dentist who must Pursue a Forensic Psychologist in The Gulf of Mexico |
    |                 0 | AGENT TRUMAN     | A Intrepid Panorama of a Robot And a Boy who must Escape a Sumo Wrestler in Ancient China                             |
    |                 0 | AIRPLANE SIERRA  | A Touching Saga of a Hunter And a Butler who must Discover a Butler in A Jet Boat                                     |
    |                 0 | AIRPORT POLLOCK  | A Epic Tale of a Moose And a Girl who must Confront a Monkey in Ancient India                                         |
    | 2.053262948989868 | ALABAMA DEVIL    | A Thoughtful Panorama of a Database Administrator And a Mad Scientist who must Outgun a Mad Scientist in A Jet Boat   |
    |                 0 | ALADDIN CALENDAR | A Action-Packed Tale of a Man And a Lumberjack who must Reach a Feminist in Ancient China                             |
    |                 0 | ALAMO VIDEOTAPE  | A Boring Epistle of a Butler And a Cat who must Fight a Pastry Chef in A MySQL Convention                             |
    |                 0 | ALASKA PHANTOM   | A Fanciful Saga of a Hunter And a Pastry Chef who must Vanquish a Boy in Australia                                    |
    |                 0 | ALI FOREVER      | A Action-Packed Drama of a Dentist And a Crocodile who must Battle a Feminist in The Canadian Rockies                 |
    |                 0 | ALICE FANTASIA   | A Emotional Drama of a A Shark And a Database Administrator who must Vanquish a Pioneer in Soviet Georgia             |
    | 1.026631474494934 | ALIEN CENTER     | A Brilliant Drama of a Cat And a Mad Scientist who must Battle a Feminist in A MySQL Convention                       |
    +-------------------+------------------+-----------------------------------------------------------------------------------------------------------------------+
    

    例8–ブールモード

    MySQLでは、ブールモードで全文検索を実行できます。これを行うには、 IN BOOLEAN MODEを追加します クエリの修飾子。

    ブールモードでは、 +などの演算子を使用できます および- 特定の単語またはフレーズが存在する必要があるかどうかを指定します。

    次の例では、各単語の前にプラス記号( + )を付けます。 )両方の単語が存在する必要があることを示します。

    SELECT 
      title, 
      description
    FROM film
    WHERE MATCH(title, description) AGAINST('+Saga +Moose' IN BOOLEAN MODE)
    LIMIT 3;
    

    結果:

    +------------------------+---------------------------------------------------------------------------------------------+
    | title                  | description                                                                                 |
    +------------------------+---------------------------------------------------------------------------------------------+
    | CAPER MOTIONS          | A Fateful Saga of a Moose And a Car who must Pursue a Woman in A MySQL Convention           |
    | DATE SPEED             | A Touching Saga of a Composer And a Moose who must Discover a Dentist in A MySQL Convention |
    | DELIVERANCE MULHOLLAND | A Astounding Saga of a Monkey And a Moose who must Conquer a Butler in A Shark Tank         |
    +------------------------+---------------------------------------------------------------------------------------------+
    

    次の例では、プラス記号の1つをマイナス記号に変更します(- )。これは、 Sagaという単語を含む行のみを意味します 返送されますが、しない場合に限ります Mooseも含まれています :

    SELECT 
      title, 
      description
    FROM film
    WHERE MATCH(title, description) AGAINST('+Saga -Moose' IN BOOLEAN MODE)
    LIMIT 3;
    

    結果:

    +------------------+-------------------------------------------------------------------------------------------------+
    | title            | description                                                                                     |
    +------------------+-------------------------------------------------------------------------------------------------+
    | AIRPLANE SIERRA  | A Touching Saga of a Hunter And a Butler who must Discover a Butler in A Jet Boat               |
    | ALASKA PHANTOM   | A Fanciful Saga of a Hunter And a Pastry Chef who must Vanquish a Boy in Australia              |
    | ARMY FLINTSTONES | A Boring Saga of a Database Administrator And a Womanizer who must Battle a Waitress in Nigeria |
    +------------------+-------------------------------------------------------------------------------------------------+
    

    マイナス記号は、他の方法で返される結果を除外するために使用されます。したがって、すべての検索語の前にマイナス記号が付いている場合は、空のセットが返されます。

    SELECT 
      title, 
      description
    FROM film
    WHERE MATCH(title, description) AGAINST('-Saga -Moose' IN BOOLEAN MODE)
    LIMIT 3;
    

    結果:

    Empty set (0.00 sec)
    

    など、ブール検索で使用できる演算子は他にもたくさんあります。 、<> * 、 もっと。ブールモードの使用の詳細については、ブール全文検索に関するMySQLのドキュメントを参照してください。

    例9–ブラインドクエリ拡張を使用

    WITH QUERY EXPANSIONを使用できます またはクエリ拡張を使用した自然言語モード ブラインドクエリ拡張を実行するための修飾子。これは、検索フレーズが非常に短い場合や、返される結果が狭すぎる可能性がある場合(したがって、関連する可能性のあるドキュメントを除外する場合)に役立ちます。

    クエリ拡張は、他の方法では返されない行を返すことにより、検索を広げることができます。特に、一致しない行に一致する行にも含まれる単語が含まれている場合、その一致しない行が一致する行になる可能性があります。つまり、一致する行と他の単語を共有しているという理由だけで、一致しない行を返すことができます。

    実例を示すために、なしの通常の検索を示します。 クエリ拡張:

    SELECT AlbumId, AlbumName
    FROM Albums
    WHERE MATCH(AlbumName) AGAINST('Blue' IN NATURAL LANGUAGE MODE);
    

    結果:

    +---------+------------+
    | AlbumId | AlbumName  |
    +---------+------------+
    |      13 | Blue Night |
    +---------+------------+
    

    IN NATURAL LANGUAGE MODEを明示的に述べました ただし、これはデフォルトのモードであるため、選択した場合はこの修飾子を省略できた可能性があります。

    そして、これがと同じ検索です クエリ拡張:

    SELECT AlbumId, AlbumName
    FROM Albums
    WHERE MATCH(AlbumName) AGAINST('Blue' WITH QUERY EXPANSION);
    

    結果:

    +---------+-----------------+
    | AlbumId | AlbumName       |
    +---------+-----------------+
    |      13 | Blue Night      |
    |      19 | All Night Wrong |
    +---------+-----------------+
    

    この場合、2つの結果が返されます。 2番目の結果に検索フレーズ( blue )が含まれていないことに注目してください )。ただし、 Nightという単語は含まれています これも最初の結果に含まれています。したがって、拡張されたクエリは、一致するのに十分であると見なします。

    アルバム名は、クエリ拡張モードのユースケースとしてはあまり適していません。より適切な使用例は、たとえばデータベースの検索です。 、拡張クエリが MySQLのような名前を含むドキュメントも返す場合があります 、 Oracle 、など、フレーズ database が含まれていない場合でも、 。

    別の例を示します。ただし、この例では二重引用符を使用して、検索語全体が存在する必要があることを指定しています。

    なしで検索を行う場合 クエリ拡張:

    SELECT 
      title, 
      description
    FROM film
    WHERE MATCH(title, description) AGAINST('"Feminist And a Mad Scientist"')
    LIMIT 3;
    

    結果:

    +------------------+--------------------------------------------------------------------------------------------------+
    | title            | description                                                                                      |
    +------------------+--------------------------------------------------------------------------------------------------+
    | ACADEMY DINOSAUR | A Epic Drama of a Feminist And a Mad Scientist who must Battle a Teacher in The Canadian Rockies |
    +------------------+--------------------------------------------------------------------------------------------------+
    

    1つの結果のみが返されます(入力されたとおりに、フレーズ全体を含む唯一の結果です)。

    ただし、ブラインドクエリ拡張を使用すると、次のようになります。

    SELECT 
      title, 
      description
    FROM film
    WHERE MATCH(title, description) AGAINST('"Feminist And a Mad Scientist"' WITH QUERY EXPANSION)
    LIMIT 3;
    

    結果:

    +--------------------+------------------------------------------------------------------------------------------------------+
    | title              | description                                                                                          |
    +--------------------+------------------------------------------------------------------------------------------------------+
    | ACADEMY DINOSAUR   | A Epic Drama of a Feminist And a Mad Scientist who must Battle a Teacher in The Canadian Rockies     |
    | DINOSAUR SECRETARY | A Action-Packed Drama of a Feminist And a Girl who must Reach a Robot in The Canadian Rockies        |
    | VICTORY ACADEMY    | A Insightful Epistle of a Mad Scientist And a Explorer who must Challenge a Cat in The Sahara Desert |
    +--------------------+------------------------------------------------------------------------------------------------------+
    

    最初の行は、クエリ拡張を使用しなかったときと同じです。ただし、クエリは実行され、検索語の一部のみを含む行を返します。 LIMIT 3 を使用したため、この結果は3つに制限されます。 。実際の結果ははるかに優れています:

    SELECT COUNT(*)
    FROM film
    WHERE MATCH(title, description) AGAINST('"Feminist And a Mad Scientist"' WITH QUERY EXPANSION);
    

    結果:

    +----------+
    | COUNT(*) |
    +----------+
    |     1000 |
    +----------+
    

    これらの結果の多くが検索用語と完全に無関係である可能性は十分にあります。したがって、ブラインドクエリ拡張は通常、短い検索用語に最適です。

    ブラインドクエリ拡張の使用の詳細については、MySQLのドキュメント:クエリ拡張を使用した全文検索を参照してください。


    1. MySQL length()とchar_length()

    2. SQLiteサンプルデータベース

    3. OracleのDATEADD()と同等の関数

    4. postgresqlにnanosecでタイムスタンプを保存する最もエレガントな方法は何ですか?