Kazuhiko
kazuh****@fdiar*****
2014年 10月 23日 (木) 20:22:08 JST
こんにちは、かずひこです。
ドキュメントを書こうとしながら、まだあれこれクエリを試していて気になった
ので質問します。
Modifier Description
+ A leading plus sign indicates that this word must be present in each
row that is returned.
- A leading minus sign indicates that this word must not be present in
any of the rows that are returned.
とありますが、以下の例では+で指定した語がないものもスコアがnon zeroな値
になります(つまり、WHEREで用いた時にマッチしてしまう)。
DROP TABLE IF EXISTS books;
CREATE TABLE books (
`id` INTEGER AUTO_INCREMENT,
`title` text,
PRIMARY KEY(`id`),
FULLTEXT INDEX title_index (title)
) ENGINE=mroonga default charset utf8;
INSERT INTO books (title) VALUES (
'Quick brown fox jumps over the lazy dog.'
);
INSERT INTO books (title) VALUES (
'Slow white fox jumps over the diligent dog.'
);
SELECT title, MATCH (title) AGAINST('+quick fox dog' IN BOOLEAN MODE) AS
score FROM books;
+---------------------------------------------+-------+
| title | score |
+---------------------------------------------+-------+
| Quick brown fox jumps over the lazy dog. | 3 |
| Slow white fox jumps over the diligent dog. | 2 |
+---------------------------------------------+-------+
2 rows in set (0.00 sec)
クエリの+wordの順序を変えると、スコアが微妙に変化します。
SELECT title, MATCH (title) AGAINST('fox +quick dog' IN BOOLEAN MODE) AS
score FROM books;
+---------------------------------------------+-------+
| title | score |
+---------------------------------------------+-------+
| Quick brown fox jumps over the lazy dog. | 3 |
| Slow white fox jumps over the diligent dog. | 1 |
+---------------------------------------------+-------+
2 rows in set (0.00 sec)
SELECT title, MATCH (title) AGAINST('fox dog +quick' IN BOOLEAN MODE) AS
score FROM books;
+---------------------------------------------+-------+
| title | score |
+---------------------------------------------+-------+
| Quick brown fox jumps over the lazy dog. | 3 |
| Slow white fox jumps over the diligent dog. | 0 |
+---------------------------------------------+-------+
2 rows in set (0.01 sec)
このように、+wordを指定しても、「wordが無いものも含まれることがある」よ
うです。ちなみに、MyISAMだと、上記の三通りとも同じ結果で、
+---------------------------------------------+-------+
| title | score |
+---------------------------------------------+-------+
| Quick brown fox jumps over the lazy dog. | 1 |
| Slow white fox jumps over the diligent dog. | 0 |
+---------------------------------------------+-------+
2 rows in set (0.00 sec)
になりました。
また、-wordの場合も同様に、「wordがある結果が必ず除外されるわけではな
い」ようです。
SELECT title, MATCH (title) AGAINST('fox dog -quick' IN BOOLEAN MODE) AS
score FROM books;
+---------------------------------------------+-------+
| title | score |
+---------------------------------------------+-------+
| Quick brown fox jumps over the lazy dog. | 0 |
| Slow white fox jumps over the diligent dog. | 2 |
+---------------------------------------------+-------+
2 rows in set (0.00 sec)
SELECT title, MATCH (title) AGAINST('fox -quick dog' IN BOOLEAN MODE) AS
score FROM books;
+---------------------------------------------+-------+
| title | score |
+---------------------------------------------+-------+
| Quick brown fox jumps over the lazy dog. | 1 |
| Slow white fox jumps over the diligent dog. | 2 |
+---------------------------------------------+-------+
2 rows in set (0.03 sec)
SELECT title, MATCH (title) AGAINST('-quick fox dog' IN BOOLEAN MODE) AS
score FROM books;
+---------------------------------------------+-------+
| title | score |
+---------------------------------------------+-------+
| Quick brown fox jumps over the lazy dog. | 2 |
| Slow white fox jumps over the diligent dog. | 3 |
+---------------------------------------------+-------+
2 rows in set (0.01 sec)
環境はMariaDB 10.0.14, Groonga 4.0.6, Mroonga 4.06です。
現状の仕様は、検索語を前から順にスコアを足しながら、+や-が来た時点で、そ
れを満たさないレコードのスコアがゼロになって、それ以降はまた順にスコアを
足していく、みたいな感じの挙動に見えます。
boolean modeと言うからには、+や-は、ドキュメントにも書いてあるように、
「絶対に含まれる」「絶対に含まれない」を意味するのが妥当と思いますが、い
かがでしょうか。
かずひこ