5.7.1. ブーリアンモード#
5.7.1.1. 概要#
Mroongaは MATCH AGAINST
に IN BOOLEAN MODE
修飾子をつけることでブーリアン全文検索を実行できます。:
SELECT ... WHERE MATCH(column) AGAINST ('...' IN BOOLEAN MODE);
通常、デフォルトの IN NATURAL LANGUAGE MODE
よりも IN BOOLEAN MODE
の方が適切です。なぜなら IN BOOLEAN MODE
はWeb検索エンジンのクエリーと似ているからです。多くのユーザーはWeb検索エンジンのクエリーに慣れています。
ブーリアン全文検索のクエリーでは MySQLがサポートしている修飾子 とMroonga独自のプラグマを使うことができます。
この修飾子とプラグマで検索結果の順位を変更できます。
修飾子もプラグマもどちらも使わずに検索した場合、検索キーワードをより多く含むレコードの方が順位が高くなります。
5.7.1.2. 使いかた#
以下は例を示すためのスキーマとデータです。:
CREATE TABLE books (
`id` INTEGER AUTO_INCREMENT,
`title` text,
PRIMARY KEY(`id`),
FULLTEXT INDEX title_index (title)
) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4;
INSERT INTO books (title) VALUES ('Professional MySQL');
INSERT INTO books (title) VALUES ('MySQL for Professional');
INSERT INTO books (title) VALUES ('Mroonga = MySQL + Groonga');
5.7.1.3. 修飾子#
サポートしている修飾子は次の通りです。
5.7.1.3.1. キーワード1 キーワード2
#
キーワード1 キーワード2
のようにキーワードの間に演算子がない場合は、指定したキーワードのどれかひとつでも含まれていればヒット、という検索条件になります。
Mroonga for
というクエリーは Mroonga
または for
が含まれているという意味です。:
SELECT title
FROM books
WHERE MATCH(title) AGAINST('Mroonga for' IN BOOLEAN MODE);
-- +---------------------------+
-- | title |
-- +---------------------------+
-- | Mroonga = MySQL + Groonga |
-- | MySQL for Professional |
-- +---------------------------+
5.7.1.3.2. キーワード1 OR キーワード2
#
OR
(大文字にすること)は左辺のキーワードまたは右辺のキーワードのうち少なくともどちらか1つは含まれていること、という意味です。
Mroonga OR for
というクエリーは Mroonga
または for
が含まれているという意味です。:
SELECT title
FROM books
WHERE MATCH(title) AGAINST('Mroonga OR for' IN BOOLEAN MODE);
-- +---------------------------+
-- | title |
-- +---------------------------+
-- | Mroonga = MySQL + Groonga |
-- | MySQL for Professional |
-- +---------------------------+
OR
はデフォルトの演算子です。省略可能です。 Mroonga OR for
と Mroonga for
はどちらも同じ結果を返します。
5.7.1.3.3. +キーワード
#
キーワードの前に「+」をつけると、そのキーワードは必ず含まれていること、という検索条件になります。
+MySQL +Mroonga
というクエリーは MySQL
も Mroonga
もどちらも含まれていること、という意味になります。:
SELECT title
FROM books
WHERE MATCH(title) AGAINST('+MySQL +Groonga' IN BOOLEAN MODE);
-- +---------------------------+
-- | title |
-- +---------------------------+
-- | Mroonga = MySQL + Groonga |
-- +---------------------------+
5.7.1.3.4. -キーワード
#
キーワードの前に「-」をつけると、そのキーワードは含まれないこと、という検索条件になります。
+MySQL -Mroonga
というクエリーは MySQL
は含まれるけど Mroonga
は含まれないという意味になります。:
SELECT title
FROM books
WHERE MATCH(title) AGAINST('+MySQL -Mroonga' IN BOOLEAN MODE);
-- +------------------------+
-- | title |
-- +------------------------+
-- | Professional MySQL |
-- | MySQL for Professional |
-- +------------------------+
5.7.1.3.5. プレフィックス*
#
プレフィックスの後に「*」をつけると、そのプレフィックスの単語を含むこと、という検索条件になります。
+M*
というクエリーは M
から始まる単語(この場合は MySQL
と Mroonga
)が含まれていること、という意味になります。:
SELECT title
FROM books
WHERE MATCH(title) AGAINST('+M*' IN BOOLEAN MODE);
-- +---------------------------+
-- | title |
-- +---------------------------+
-- | Mroonga = MySQL + Groonga |
-- | Professional MySQL |
-- | MySQL for Professional |
-- +---------------------------+
注釈
正確に言うと、「単語」はあなたが思っている「単語」ではないかもしれません。この文脈での「単語」は「トークン」ということです。「トークン」は単語ではないかもしれません。たとえば、「It's」の中のトークンは「It」と「'」と「s」です。
mroonga_command() と tokenize を使うとトークンを確認できます。:
SELECT mroonga_command('tokenize TokenBigram "It''s" NormalizerMySQLGeneralCI');
-- +--------------------------------------------------------------------------+
-- | mroonga_command('tokenize TokenBigram "It''s" NormalizerMySQLGeneralCI') |
-- +--------------------------------------------------------------------------+
-- | [ |
-- | { |
-- | "value":"IT", |
-- | "position":0, |
-- | "force_prefix":false |
-- | }, |
-- | { |
-- | "value":"'", |
-- | "position":1, |
-- | "force_prefix":false |
-- | }, |
-- | { |
-- | "value":"S", |
-- | "position":2, |
-- | "force_prefix":false |
-- | } |
-- | ] |
-- +--------------------------------------------------------------------------+
上の結果のJSONの値は手で整形しています。
5.7.1.3.6. "フレーズ"
#
ダブルクォート( "
)でフレーズを囲むと、そのフレーズが必ず含まれていること、という検索条件になります。
+"Professional MySQL"
というクエリーは Professional MySQL
というフレーズが含まれていること、という意味になります。このクエリーは MySQL for Profession
にはマッチしません。 MySQL for Profession
は MySQL
という単語も Professional
という単語も含んでいますが、 Professional MySQL
というフレーズは含んでいません。:
SELECT title
FROM books
WHERE MATCH(title) AGAINST('+"Professional MySQL"' IN BOOLEAN MODE);
-- +--------------------+
-- | title |
-- +--------------------+
-- | Professional MySQL |
-- +--------------------+
5.7.1.3.7. (サブ式...)
#
カッコを使うと式をグルーピングできます。
+(Groonga OR Mroonga) +MySQL
というクエリーは次のような意味です。
Groonga
あるいはMroonga
のどちらかが含まれている。
MySQL
が含まれている。
以下はこのクエリーの実行結果です。:
SELECT title
FROM books
WHERE MATCH(title) AGAINST('+(Groonga OR Mroonga) +MySQL' IN BOOLEAN MODE);
-- +---------------------------+
-- | title |
-- +---------------------------+
-- | Mroonga = MySQL + Groonga |
-- +---------------------------+
5.7.1.4. プラグマ#
プラグマはクエリーのメタデータです。プラグマを指定することでクエリーのパース方法を変更できます。
実行方法をカスタマイズするためにクエリーの先頭にプラグマを埋め込むことができます。
プラグマはクエリーの先頭になければいけません。クエリーの先頭に空白を入れてはいけません。プラグマは *
から始まります。:
SELECT MATCH AGAINST('*PRAGMA ...' IN BOOLEAN MODE);
複数のプラグマを指定することができます。:
SELECT MATCH AGAINST('*PRAGMA1PRAGMA2 ...' IN BOOLEAN MODE);
以下は利用可能なプラグマの一覧です。
5.7.1.4.1. D
プラグマ#
D
プラグマはデフォルトの演算子を指定します。個別の演算子を省略するとデフォルトの演算子を使います。
D
プラグマの構文は次の通りです。 ${OPERATOR}
には OR
または +
または -
を指定します。:
*D${OPERATOR}
5.7.1.4.1.1. DOR
#
DOR
はデフォルトの演算子として「OR」を使うという意味です。
これがデフォルトです。
DOR
を使う例は次の通りです。 '*DOR for Mroonga' IN BOOLEAN MODE
は for
または Mroonga
を含むという意味です。
SELECT title
FROM books
WHERE MATCH (title) AGAINST('*DOR for Mroonga' IN BOOLEAN MODE);
-- +---------------------------+
-- | title |
-- +---------------------------+
-- | MySQL for Professional |
-- | Mroonga = MySQL + Groonga |
-- +---------------------------+
5.7.1.4.1.2. D+
#
D+
はデフォルトの演算子として「AND」を使うという意味です。これはWeb検索エンジンのクエリーと同じ挙動です。
D+
を使う例は次の通りです。 '*D+ MySQL Mroonga' IN BOOLEAN MODE
は MySQL
と Mroonga
の両方を含むという意味です。:
SELECT title
FROM books
WHERE MATCH (title) AGAINST('*D+ MySQL Mroonga' IN BOOLEAN MODE);
-- +---------------------------+
-- | title |
-- +---------------------------+
-- | Mroonga = MySQL + Groonga |
-- +---------------------------+
5.7.1.4.1.3. D-
#
D-
はデフォルトの演算子として「NOT」を使うという意味です。
D-
を使う例は次の通りです。 '*D- MySQL Mroonga' IN BOOLEAN MODE
は MySQL
を含むが Mroonga
を含まないという意味です。:
SELECT title
FROM books
WHERE MATCH (title) AGAINST('*D- MySQL Mroonga' IN BOOLEAN MODE);
-- +------------------------+
-- | title |
-- +------------------------+
-- | Professional MySQL |
-- | MySQL for Professional |
-- +---------------------------+
5.7.1.4.2. W
プラグマ#
W
プラグマはマルチカラムインデックス用のプラグマです。検索対象のセクションとその重みを指定します。
各セクションごとに違う重みを指定できます。デフォルトの重みは 1
です。 1
は重みがないという意味です。
W
プラグマの構文は次の通りです。 ${SECTION}
は0ではなく1から始まる数値です。 ${WEIGHT}
は省略可能です。:
*W[${SECTION1}[:${WEIGHT1}]][,${SECTION2}[:${WEIGHT2}]][,...]
次は例を示すためのスキーマとデータです。 W
プラグマを使うためにはマルチカラムインデックスを作る必要があります。:
CREATE TABLE memos (
`id` INTEGER AUTO_INCREMENT,
`title` text,
`content` text,
PRIMARY KEY(`id`),
FULLTEXT INDEX text_index (title, content)
) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4;
INSERT INTO memos (title, content) VALUES (
'MySQL', 'MySQL is a RDBMS.'
);
INSERT INTO memos (title, content) VALUES (
'Groonga', 'Groonga is a full text search engine.'
);
INSERT INTO memos (title, content) VALUES (
'Mroonga', 'Mroonga is a storage engine for MySQL based on Groonga.'
);
次の例は重みの使い方を示す例です。 title
カラムは重みが 10
で、 content
カラムは重みが 1
です。これは title
カラムの中にあるキーワードは content
カラムの中にあるキーワードよりも10倍重要だということです。
SELECT title,
content,
MATCH (title, content) AGAINST('*W1:10,2:1 +Groonga' IN BOOLEAN MODE) AS score
FROM memos;
-- +---------+--------------------------------------------------------+-------+
-- | title | content | score |
-- +---------+--------------------------------------------------------+-------+
-- | MySQL | MySQL is a RDBMS. | 0 |
-- | Groonga | Groonga is a full text search engine. | 11 |
-- | Mroonga | Mroonga is a storage engine for MySQL based on Groonga | 1 |
-- +---------+--------------------------------------------------------+-------+
最初のレコードのスコアーは 0
です。なぜなら、 title
カラムにも content
カラムにも Groonga
が含まれていないからです。
二つめのレコードのスコアーは 11
です。なぜなら、 title
カラムにも content
カラムにもどちらにも Groonga
が含まれているからです。 title
カラム内の Groonga
のスコアーは 10
です。 content
カラム内の Groonga
のスコアーは 1
です。 11
はこれらのスコアーの合計値です。
三つめのレコードのスコアーは 1
です。なぜなら、 content
カラムにだけ Groonga
が含まれているからです。 content
カラムの Groonga
のスコアーは 1
です。そのため、このレコードのスコアーは 1
になります。
5.7.1.4.3. S
プラグマ#
S
プラグマはクエリーの構文を指定します。
S
プラグマの構文は次の通りです。:
*S${SYNTAX}
利用可能な syntax
は次の通りです。
S
: スクリプト構文
5.7.1.4.3.1. *SS
#
*SS
プラグマを使うと スクリプト構文 を使えます。スクリプト構文ではGroongaのすべての検索機能を使えます。
以下はスクリプト構文の使い方を示す例のためのスキーマとデータです。:
CREATE TABLE comments (
`content` text,
FULLTEXT INDEX content_index (content)
) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4;
INSERT INTO comments VALUES (
'A student started to use Mroonga storage engine. It is very fast!'
);
INSERT INTO comments VALUES (
'Another student also started to use Mroonga storage engine. It is very fast!'
);
以下はスクリプト構文で 近傍検索 を使う例です。:
SELECT content,
MATCH (content) AGAINST('*SS content *N "student fast"' IN BOOLEAN MODE) AS score
FROM comments;
-- +------------------------------------------------------------------------------+-------+
-- | content | score |
-- +------------------------------------------------------------------------------+-------+
-- | A student started to use Mroonga storage engine. It is very fast! | 1 |
-- | Another student also started to use Mroonga storage engine. It is very fast! | 0 |
-- +------------------------------------------------------------------------------+-------+
近傍検索は指定した単語間(今回の場合は student
と fast
)に10単語以下しかない場合のみマッチします。そのため、 student started ...(8単語)... very fast
はマッチしますが、 student also started ...(8単語)... very fast
はマッチしません。
他の上級者向け機能も使えます。